首页 文章

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

提问于
浏览
2

我正在阅读有关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 是否已完全更新?

1 回答

  • 3

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

    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
      )
    }
    

相关问题