Есть ли какой-нибудь способ преодолеть .map не является ошибкой типа функции?

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я создаю приложение для заказа еды, используя react.Я создал серверную часть для вызовов api, кажется, она работает нормально.Я застрял в этом.state.filteredRestaurantList.map не является ошибкой функции.Есть ли какое-либо решение для этого? Должен ли я изменить экспорт по умолчанию или есть какой-либо другой способ. Это из-за getGridListCols!

 
class Home extends React.Component {

  constructor(props){
    super(props);
    this.state = {
        restaurantList: [],
        filteredRestaurantList: [],
        }
    }

  getGridListCols = () => {
      if (isWidthUp('xl', this.props.width)) {
        return 6;
      }

      if (isWidthUp('lg', this.props.width)) {
        return 5;
      }

      if (isWidthUp('md', this.props.width)) {
        return 4;
      }
      if (isWidthUp('sm', this.props.width)) {
        return 2
      }
      return 1;
  }

  searchHandler = (value) => {
    if (value !== '') {
      this.findRestaurantApiCall(value);
    }else {
      this.getAllRestaurantsApiCall();
    }
  }

  itemClickHandler= (id)=>{
    console.log('id',id);
    this.props.setRestaurantId(id);
    this.props.history.push('/details');
  }

  render(){
    return(
      <div style={{marginTop:100}}>
        <Header screen="Home" searchHandler={this.searchHandler}/>
        <div>
          <GridList cellHeight={'auto'} cols={this.getGridListCols()}>
            {this.state.filteredRestaurantList.map(item =>(
              <GridListTile key={item.id}>
                <HomeItem onItemClick={this.itemClickHandler} item={item} />
              </GridListTile>
            ))}
          </GridList>
        </div>
      </div>
    );
  }

  componentDidMount(){
    this.getAllRestaurantsApiCall();
  }

  getAllRestaurantsApiCall = () => {
    let that = this;
    let url = `http://localhost:8080/api/restaurant`;
    return fetch(url,{
      method:'GET',
    }).then((response) =>{
      if (response.ok) {
        return response.json();
      }
    }).then((responseJson)=>{
      that.setState({
        restaurantList:responseJson,
        filteredRestaurantList:responseJson
      });
    }).catch((error) => {
      console.log('error login data',error);
    });
  }

  findRestaurantApiCall = (value) => {
    let that = this;
    let url = `http://localhost:8080/api/restaurant/name/${value}`;
    return fetch(url,{
      method:'GET',
    }).then((response) =>{
      if (response.ok) {
        return response.json();
      }
    }).then((responseJson)=>{
      console.log('json',responseJson);
      that.setState({
        restaurantList:responseJson,
        filteredRestaurantList:responseJson
      });
    }).catch((error) => {
      console.log('error login data',error);
    });
  }

}

function HomeItem(props){
  const{item} = props;
  return(
    <div className="home-item-main-container">
      <Card style={{width:280}}>
        <CardActionArea onClick={(e)=>props.onItemClick(item.id)}>
          <CardMedia
            component="img"
            alt={item.restaurantName}
            style={{objectFit: 'cover'}}
            height="140"
            image={item.photoUrl}
            title={item.restaurantName}/>
          <CardContent>
            <Typography gutterBottom variant="h5" component="h2">
              {item.restaurantName}
            </Typography>
            <Typography component="p">
              {item.categories}
            </Typography>
            <div style={{marginTop:25,display:'flex',justifyContent:'space-between',alignItems:'center'}}>
              <div style={{display:'flex',flexDirection:'row',backgroundColor:"#FDD835",padding:5,justifyContent:'space-evenly',alignItems:'center',width:80}}>
                <FontAwesomeIcon icon="star" color="white"/>
                <span className="white">{item.userRating}({item.numberUsersRated})</span>
              </div>
              <div>
                <FontAwesomeIcon size="sm" icon="rupee-sign" color="black"/>
                <span>{item.avgPrice} for two</span>
              </div>
            </div>
          </CardContent>
        </CardActionArea>
      </Card>
    </div>
  )
}

export default withWidth(Home);

  

Я ожидаю, что моя домашняя страница отображается без каких-либо ошибок

Комментарии:

1. вы уже выполнили какую-либо отладку?

2. Какую ошибку вы получаете? Отсюда похоже, что ваша карта должна работать просто отлично

3. @ChrisBrownie55 Нет, если filteredRestaurantList не определен при первом рендеринге, это выдаст ошибку, потому что map не является свойством неопределенного типа. Я отвечу на это

4. При первом рендеринге, filteredRestaurantList как [] определено в конструкторе, оно может стать неопределенным, только если какая-либо другая функция (или редуктор) изменяет его

5. @SterlingArcher Ах да, я не смог увидеть конструктор в предоставленном коде. Это именно то, что вы сказали, возможно, это происходит в filtering stage (как следует из названия переменной состояния) или, в худшем случае, когда ответ от API присваивается свойству state. (в этом случае все должно прерваться до render()) 😉

Ответ №1:

Если вы получаете данные из серверной части, то сначала вам следует проверить, filteredRestaurantList является ли массив, который можно выполнить следующим образом

 this.state.filteredRestaurantList amp;amp; this.state.filteredRestaurantList.map(...)
  

Скорее всего, это проблема здесь. Компилятор выдает ошибку, потому что, map() разрешено для значений типа массива.

Надеюсь, это поможет!

Комментарии:

1. Как мне отредактировать код, серверная часть работает нормально!

2. Вам нужно изменить this.state.filteredRestaurantList.map на то, что я предложил выше в render методе Home компонента

3. Я пробовал это самым первым, но ничего не меняется

Ответ №2:

вы можете использовать деструкцию объекта

 class Home extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            restaurantList: [],
            filteredRestaurantList: [],
        }
    }

    render(){
        const { filteredRestaurantList = [] } = this.state;

        return(
          <div style={{marginTop:100}}>
            <Header screen="Home" searchHandler={this.searchHandler}/>
            <div>
              <GridList cellHeight={'auto'} cols={this.getGridListCols()}>
                {filteredRestaurantList.map(item =>(
                  <GridListTile key={item.id}>
                    <HomeItem onItemClick={this.itemClickHandler} item={item} />
                  </GridListTile>
                ))}
              </GridList>
            </div>
          </div>
        );
      }
  

Комментарии:

1. ‘filteredRestaurantList’ не определен no-undef