简体   繁体   中英

React - this.props.appRecommendData.map is not a function

I am a beginner at ReactJS, I aim to make an app searching web application. Here is my idea:
In app.js , I have a state: appRecommendData which retrieve the result from the app store API and do searching by a function filterAppRecommend() , and then rendered by a component called AppRecommend , I found that I cannot render the result initially, but it works after typing, because of the async problem(when I still fetching the data, the export function have started), then I tried to add async and await to solve it, it works but the props.map is not function, can anyone help to solve it/suggest other way to fix it? below is my code:
app.js :

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      filteredAppList: [],
      filteredRecommend:filterAppRecommend("",10)
    };
  }
  handleSearchChange = event =>{
    this.setState({
                  filteredRecommend:filterAppRecommend(event.target.value,10)
                });
  }
  render() {

    return (
      <div className="App">
        <header className="App-header">
        <div className="search-bar"><SearchInput textChange={this.handleSearchChange} /></div>     
          <div className="App-recommendation">
            <AppRecommend appRecommendData={this.state.filteredRecommend}/>
          </div>
        </header>
      </div>
    );
  }
}
}

In filterAppRecommend.js :

export default async function filterAppRecommend(searchText, maxResults) {
    console.log("maxResults is"+maxResults);
    const api = await fetch("https://itunes.apple.com/hk/rss/topgrossingapplications/limit=10/json")
  .then(results=>results.json());
      console.log(api);
      let datas = api.feed.entry;
      console.log(datas);
    return datas.filter(data => {
        if(searchText===""){
          return true;
      }
      if (data["im:name"].label.toLowerCase().includes(searchText.toLowerCase())) {
        return true;
      }
      if (data["im:name"].label.includes(searchText)) {
        return true;
      }
      return false;
    })
    .slice(0, maxResults);

}

In Component AppRecommend :

class AppRecommmend extends PureComponent{
    constructor(props){
        super(props);
        this.state = {
            isLoading:false,
        };
    }
    render(){
        console.log(this.props.appRecommendData.type); //will show undefined
        return(
        <div className="component-AppRecommend">
        {this.props.appRecommendData.map(appRecommendData=>(
            <AppRecommmendCol
            imgSource={appRecommendData["im:image"][1].label}
            title={appRecommendData["im:name"].label}/>
        ))}
        </div>
    );}
}
AppRecommmend.propTypes = {
  appRecommendData: PropTypes.oneOfType([
      PropTypes.object,
      PropTypes.array
  ])
}
export default AppRecommmend

Since you use .map to go through collection of data, appRecommendData should be an array. filterAppRecommend should return data as array. You can use sth like this to get initial value:

//App.js

async componentDidMount() {
   const filteredRecommend = await filterAppRecommend("",10);
   this.setState({ filteredRecommend });
}

In AppRecommmend.js use

AppRecommmend.defaultProps = {
appRecommendData : []
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM