9

enter image description here

I couldn't understand why...here is the GitHub repository: https://github.com/Dronrom/React-test

Wolfizzy
  • 581
  • 1
  • 4
  • 18
Roman Devda
  • 95
  • 1
  • 1
  • 3

5 Answers5

14

That’s because you initialized peopleList as null in your component. So map works only on arrays so you need to check peopleList whether its really an array before doing map on it so

Change

   renderItems(arr) {
    return arr.map(({id, name}) => {
        return (
            <li className="list-group-item"
                key={id}
                onClick={() => this.props.onItemSelected(id)}>
                 {name}
            </li>
        );
    });
}

To

  renderItems(arr) {
      if(arr){
            return arr.map(({id, name}) => {
                 return (
                     <li className="list-group-item"
                key={id}
                onClick={() => this.props.onItemSelected(id)}>
                        {name}
                    </li>
                );
            });
         }
      }
Hemadri Dasari
  • 32,666
  • 37
  • 119
  • 162
1

I think your issue may be that react renders once before componentDidMount(). This is an issue because your calling map on arr which is null. const { peopleList } = this.state; you set people list to your current state which you set as default to be null, state = {peopleList: null}; then you later call this.renderItems(peopleList); which people list is still null at this moment so you are getting the Cannot read property 'map' of null error. I belive something like componentWillMount is what you need instead. I recommend looking at this post which has a similar issue of react life cycle methods. React render() is being called before componentDidMount()

M4rk
  • 69
  • 2
0

the answer is very simple: the type of the input isn't array type, it might be null or undefined. so that it doesn't have .map function.

How to fix:

  • Make sure your input must be array type before call renderItems().
    render(){
        const { peopleList } = this.state;


        const items = (peopleList && peopleList.length) ? this.renderItems(peopleList) : null;

        return(
            <ul className="item-list list-group">
                {items}
            </ul>
        );
    }

Or:

  • Make sure your input must be array type before do mapping:

       renderItems(arr) {
          return !arr ? null : arr.map(({id, name}) => {
            return (
                 <li className="list-group-item"
                     key={id}
                     onClick={() => this.props.onItemSelected(id)}>
                      {name}
                 </li>
             );
           });
Kai
  • 3,104
  • 2
  • 19
  • 30
0
{product.size?.map(c=>(

                <FilterSizeOption key={c}>{c}</FilterSizeOption>
                ))}
Mr S
  • 1
0

Wrapping the return statement with a if statement worked for me

So changed

return (
  <div>
    <Navbar />
    {countries.map((country, i) => {
      return (
        <div>
          <span key={`${country.name.common}${i}`}>
            {country.name.common}
          </span>
        </div>
      );
    })}
  </div>
);

to this

  if (countries) {
return (
  <div>
    <Navbar />
    {countries.map((country, i) => {
      return (
        <div>
          <span key={`${country.name.common}${i}`}>
            {country.name.common}
          </span>
        </div>
      );
    })}
  </div>
);

}

dafydd j
  • 31
  • 2