如何在React中通过事件处理程序更新和使用状态

4

我有一个名为Searcher的组件,其中有一个函数SearchArticle(),在组件挂载后会正确地使用this.state.search的默认值(控制台显示Searching...:DEFAULT)。但是当我通过handleKeyPress(e)更新this.state.search时,同样的函数SearchArticle()将使用更新前的prevState而不是更新后的e.target值(控制台再次显示Searching...:DEFAULT)。不确定如何解决这个问题。

class Searcher extends Component {

    constructor(props) {
        super(props);
        this.state = { 
            article: [], search: "DEFAULT"
        }; 
    }  

    searchArticle() { 
        console.log('Searching...: ', this.state.search)                                 
    }

    handleKeyPress = (e) => {
        if (e.key === 'Enter') {                            
            this.setState({search: e.target.value});
            this.searchArticle();
        }
    }

    componentDidMount() {
        this.searchArticle();     
    } 

    render() {
        return (
            <div className="row">
            Search: <input onKeyPress={this.handleKeyPress} type="text" />
            </div>            
        )
    }

}
1个回答

7

很可能在执行console.log时状态还没有更新,这是因为setState()是异步的。

所以请尝试以下方式:

handleKeyPress = (e) => {
  if (e.key === 'Enter') {                            
    this.setState({search: e.target.value}, () => {
       this.searchArticle();
    });       
  }
}

我将你的 searchArticle() 移到了 setState() 的回调函数中。这样做可以保证在状态实际更新之后才执行。


关于 setState() 的更多信息请阅读此处

setState() 视为请求而不是立即更新组件的命令。出于性能考虑,React 可以延迟更新并在单个传递中更新多个组件。React 不能保证状态更改会立即应用。

setState() 不一定会立即更新组件。它可能会批量或延迟更新。因此,在调用 setState() 后立即读取 this.state 是潜在的陷阱。相反,请使用 componentDidUpdatesetState 回调(setState(updater, callback)),二者都保证在更新应用后触发。

[...]

setState() 的第二个参数是一个可选的回调函数,一旦 setState 完成并重新渲染组件,它将被执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接