简体   繁体   中英

Can I use “this.props” in componentDidMount? Error:Uncaught TypeError: Cannot read property 'map' of undefined

In componentDidMount to selectTodo , assign this.props.selected . In the console, I check that selectTodo is an object that contains an array of comments . I am trying to get to this array but I get an error: Error:

Uncaught TypeError: Can not read property 'map' of undefined

class Details extends Component {
  constructor() {
    super();


    this.state = {
      resul: []
      selectTodo:[]
    }; 
  }

  componentDidMount() {
    axios.get(" http://....../todos")
      .then(response => {
        this.setState({
          resul: response.data,
          selectTodo: this.props.selected
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', Error);
      }
    );
  }


  render () {

    return (
      <div>    
        {
          { 
              this.state.selectTodo.comments.map((obj, i) => {
                return <li>{obj["comment"]}</li>
              })  
            } 
        }
      </div>      
    );
  }
}



export default Details;

Console.log

 console.log(this.state.selectTodo);


 return:


Object
  comments: (2) [{'comment': 'sdsd'}, {'comment': 'sdsdsdsds'}]
  id: 1

Error: Uncaught TypeError: Cannot read property 'map' of undefined

First thing, the data that you define in state and loop in the render does not look good for me. I mean, you define selecTodo as an array in constructor and trying to get as selectTodo.comments in the render method. So, change the state to

    this.state = {
      resul: []
      selectTodo:{comments: []}
    };

And change the way you assign the data in componentDidMount as

  componentDidMount() {
    axios.get(" http://....../todos")
      .then(response => {
        this.setState({
          resul: response.data,
          selectTodo: { comments: this.props.selected.comments }
        });
      })
      .catch(error => {
        console.log('Error fetching and parsing data', Error);
      }
    );
  }

and do the following in render

  render () {
    if(!this.state.selectedTodo.comments.length) {
      return null;
    }
    return (
      <div>    
        {
          { 
              this.state.selectTodo.comments.map((obj, i) => {
                return <li>{obj["comment"]}</li>
              })  
            } 
        }
      </div>      
    );
  }

the undefined comes from the fact that componentDidMount happens after the first render, so when the first render occurs this.state.selectTodo is still undefined.

One way of solving that is inside the render checking if this.state.selectTodo exists and only if it exists return the div with the map, otherwise return a spinner or something else.

Does this make sense?

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