来自 jsx 元素的 React 事件目标值未绑定到状态和 json 数组(类型错误无法读取 undefined 的属性)

React event target value from jsx element does not get bind to state and json array (Type error cannot read the properties of undefined )

我正在尝试绑定来自 select 选项标签的事件的值,该标签具有从 mongodb 获取的数据,用于在 componentDidMount 期间填充在 select 下拉列表中的位置( ) 生命周期方法调用。

我想实现一种功能,当我 select 来自 select 的值删除来自其他 api (餐馆)的相应值时,应该填充。

但问题是 fetch url promise 似乎没有解决并且没有绑定到 state.restaurants 数组以在输入类型文本框中创建 ul 元素。这是我的代码

export default class Vrestauranthome extends Component {
  constructor() {
    super();
    console.log('Home is called vrestaurant');
    this.state = {
      locations: [],
      restaurants: [],
    };
  }

  componentDidMount() {
    console.log('Wallpaper componentDidMount getting called....', this.state);

    fetch('http://localhost:5252/zomato/locations', { method: 'GET' })
      .then((response) => response.json())
      .then((data) => this.setState({ locations: data.data }));
  }

  fetchRestaurants = (event) => {
    fetch(`http://localhost:5252/zomato/restaurants/${event.target.value}`, {
      method: 'GET',
    })
      .then((response) => response.json())
      .then((data) => {
        this.setState({ restaurants: data.data });
        console.log(data.data);
      });
  };

  render() {
    if (!this.state.locations || !this.state.restaurants) {
      return <>Loading data...</>;
    }
    
    let locationList =
      this.state.locations.length &&
      this.state.locations.map((item) => (
        <option key={item.name} value={item.city_id}>
          {item.name}
        </option>
      ));

    let restaurantList = this.state.restaurants.length && (
      <ul>
        {this.state.restaurants.map((item) => (
          <li key={item.name}>{item.name}</li>
        ))}
      </ul>
    );

    return (
      <div className='ContainerHome'>
        <div className='location-selector' style={{ paddingLeft: '90px' }}>
          <select
            className='locationDropdown px-3'
            onChange={this.fetchRestaurants}
          >
            <option value='0' style={{ display: 'none' }}>
              Please type a location
            </option>
            {locationList}
          </select>
        </div>
        <div className='restaurantSelector' style={{ paddingLeft: '90px' }}>
          <input
            className='searchForRestaurantinputBOX'
            type='text'
            placeholder='  Search for restaurants'
            style={{
              paddingLeft: '50px',
              fontFamily: 'Poppins',
              opacity: '85%',
            }}
          />
          {restaurantList}
        </div>
      </div>
    );
  }
}

当我使用 fetch 方法使用 event.target.value 从 url 获取数据时,它显示了当我控制台记录它时的值,但它似乎没有与 url 绑定用于使用后端 api 路由从 mongodb 数据库获取数据。

这在 mongo 数据库中,分别作为 Locations 和 Restaurants 集合。

我将 city_id 从位置映射到 Restaurants.city 以获取要填充到搜索输入框中的值。

[{"name":"ShalimarBhagh, Delhi","city_id":"1","location_id":"1","country_name":"India"}]

[{"name":"Gulab","city_name":"Delhi","city":"1","area":"11"}]

当我 select 从下拉列表中选择一个选项时,它就会消失并在下面抛出错误: 它在浏览器中显示错误:Uncaught TypeError: Cannot read properties of undefined (reading 'length')

这里是当我 select 来自以下内容时检查浏览器中显示的内容:

您应该在显示之前检查数据是否已加载。
render 方法中添加检查应该可以防止错误:

render() {
    if (!this.state.locations || !this.state.restaurants) {
      return <>Loading data...</>;
    }
    
    let locationList =
      this.state.locations.length &&
      this.state.locations.map((item) => (
        <option key={item.name} value={item.city_id}>
          {item.name}
        </option>
      ));

    let restaurantList = this.state.restaurants.length && (
      <ul>
        {this.state.restaurants.map((item) => (
          <li key={item.name}>{item.name}</li>
        ))}
      </ul>
    );

    ...
}

此外,尝试像这样更改您的 setState 调用:

fetch('http://localhost:5252/zomato/locations', { method: 'GET' })
  .then((response) => response.json())
  .then((data) =>
    this.setState({
      ...this.state,
      locations: data.data,
    })
  );

...

fetch(`http://localhost:5252/zomato/restaurants/${event.target.value}`, {
  method: 'GET',
})
  .then((response) => response.json())
  .then((data) => {
    this.setState({ ...this.state, restaurants: data.data });
  });

经过多次尝试并使功能组件与此相同后,我发现了错误。

应该是data => this.setState({restaurants:data.result})。更新后返回结果。

这是因为在后端它 return 从 mongoose 模型获取数据后结果变量。嘘。