setState没有在我的其他方法中更新

时间:2020-05-28 13:44:53

标签: reactjs

我是一个很新的反应者,我很困惑为什么我的状态没有用我的另一种方法更新,请参见下面的示例。

fetchMovies = () => {
    const self = this;
    axios.get("https://api.themoviedb.org/3/trending/movie/day?api_key=XXXXXXX")
        .then(function(response){
            console.log(response.data)
            self.setState({
                collection: response.data.results
            })
            console.log(self.state.collection)
        });
}

makeRow = () => {
    console.log(this.state.collection.length);
    if(this.state.collection.length !== 0) {
        var movieRows = [];
        this.state.collection.forEach(function (i) {
            movieRows.push(<p>{i.id}</p>);
        });

        this.setState({
            movieRow: movieRows
        })
    }

}

componentDidMount() {
    this.fetchMovies();
    this.makeRow();
}

当在fetchMovies函数内部时,我可以访问集合,并且它具有所有数据,但这是我在控制台记录状态时在makeRow函数中无法理解的部分,我希望更新后的状态显示在此处,但是我什至不按顺序执行功能。

谢谢。

2 个答案:

答案 0 :(得分:1)

setState()文档包含以下段落:

setState()视为请求,而不是立即命令 更新组件。为了获得更好的感知性能,React可能会 延迟它,然后一次通过更新几个组件。反应 不保证状态更改会立即应用。

要访问修改后的状态,您需要使用功能签名setState(updater, [callback]),因此您应该使用它;

self.setState({
    collection: response.data.results
}, () => { // Will be executed after state update
  console.log(self.state.collection) 
  // Call your make row function here and remove it from componentDidMount if that is all it does.
  self.makeRow()
} )

答案 1 :(得分:1)

  1. 在异步调用解决后设置集合。即使在makeRow之后调用fetchMoview方法(异步调用的原因),您也永远不知道何时将解决该调用并设置收集状态。

  2. 无需保持movieRows的状态,这只是呈现所需的状态。保持html样机状态永远不是一个好主意。

因此,您应该只在fetchMoviews中调用componentDidMount并按如下所示呈现数据:

render() {
 const { collection } = this.state;

 return (
  <>
   {
     collection.map(c => <p>{c.id}</p>)
   }
  </>
 )
}

确保状态下collection的初始值为[]