如何知道所有 setState 更新是不是已应用于 React 组件中的状态?

Posted

技术标签:

【中文标题】如何知道所有 setState 更新是不是已应用于 React 组件中的状态?【英文标题】:How to know if all the setState updates have been applied to the state in a React component?如何知道所有 setState 更新是否已应用于 React 组件中的状态? 【发布时间】:2017-10-11 03:21:48 【问题描述】:

我正在阅读有关 React setState 的文档,其中说:

setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。

现在我有一个这样的组件:

class NoteScreenComponent extends React.Component 

    constructor() 
        super();
        this.state =  note: Note.newNote() 
    

    componentWillMount() 
        this.setState( note: this.props.note );
    

    noteComponent_change = (propName, propValue) => 
        this.setState((prevState, props) => 
            let note = Object.assign(, prevState.note);
            note[propName] = propValue;
            return  note: note 
        );
    

    title_changeText = (text) => 
        this.noteComponent_change('title', text);
    

    body_changeText = (text) => 
        this.noteComponent_change('body', text);
    

    saveNoteButton_press = () => 
        // Save note to SQL database
        Note.save(this.state.note)
    

    render() 
        return (
            <View>
                <TextInput value=this.state.note.title onChangeText=this.title_changeText />
                <TextInput value=this.state.note.body  onChangeText=this.body_changeText />
                <Button title="Save note" onPress=this.saveNoteButton_press />
            </View>
        );
    


我想知道的是,由于setState 不会立即更新state,我怎么知道我保存在saveNoteButton_press 中的注释是否是状态的当前版本?是否有一些回调或我可以轮询以了解 state 是否已完全更新?

【问题讨论】:

render() 作为告诉你状态更新完成的回调怎么样?我们知道它已经准备好了,对吧? 【参考方案1】:

他们警告的是试图在同一个事件循环中做某事。

method = () => 
  this.setState( note: 'A' )
  saveNote(this.state.note) // <-- this.state.note will not have been updated yet.

或使用以前的状态到setState

method = () => 
  let note = this.state.note // possible that `this.state.note` is scheduled to change
  this.setState( note: note + 'B' )

由于您的用户将在 setState 调度后按下按钮,因此状态已经更新。

..但是为了理论上的缘故,让我们假设输入事件和按钮以某种方式发生在完全相同的时刻..正确的解决方案是什么?如果是单个函数调用,您可能不会使用新状态,因为您已经拥有新注释和之前的状态。

method = (text) => 
  let noteToSave = this.state.note + text // old state + new value

  saveNote(noteToSave) // maybe this will fail
    .then(response => this.setState( note: noteToSave ))
    .catch(err => this.setState( error: 'something went wrong' ))

  // optimistically update the ui
  this.setState( note: noteToSave ) 

但可能最有可能的解决方案是将您想要的作为参数传递给您使用它,而不是尝试访问 可能处于竞争状态的状态,因为render 将在任何状态转换之后发生。

method = (note) => 
  noteToSave(note)


render() 
  return (
    <Button onPress=() => this.method(this.state.note) /> <-- must be up to date here
  )

【讨论】:

以上是关于如何知道所有 setState 更新是不是已应用于 React 组件中的状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何访问已调用 setState 的函数主体中的更新状态?

React 警告:setState(...) 只能更新已安装或正在安装的组件

“警告:setState(...):只能更新已安装或已安装的组件”是啥意思?

渲染后如何根据另一个状态使用 setState 更新状态?

onChange on input不使用setState更新状态

每 5 秒更新一次文本小部件,而不在颤动中使用“setstate()”