如何在react中同步设置多个值的状态?

时间:2018-04-10 15:10:08

标签: reactjs synchronization

我有一个具有4个不同状态值的React组件:

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            value: '',
            intents: [],
            selected_tags: [],
            unselected_tags: []};

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.checkIntersection = this.checkIntersection.bind(this);
        this.setTags = this.setTags.bind(this);
}

value更新,因为用户键入消息,服务器响应填充intents,其他两个根据intents中的项目遵循逻辑:

this.setState({
    intent: ['a','b','c'...n],
    selected_tags: data.filter(tag => this.checkIntersection(['b','c','d'], this.state.intent).size !== 0), 
    unselected_tags: data.filter(tag => !this.state.selected_tags.includes(tag))
)}

问题在于我似乎无法同步更新后三者(intentsselected_tagsunselected_tags)。这是至关重要的,因为selected_tags的内容取决于intentsunselected_tags的内容取决于selected_tags

我设法迫使selected_tags等待intents使用Promises [{1}}和.then()填充,以使用unselected_tags等待selected_tags

setTimeout()

但是,我很确定这不是' React'这样做的方式,主要是因为我不知道服务器需要多长时间来实时响应,因此使用axios.get('http://localhost:3001', { params: { text: this.state.value } }) .then(response => this.setState({ intent: [....]) })) .then(setTags) setTags() { if (this.state.intent !== []) { this.setState( { selected_tags: data.filter(tag => this.checkIntersection(tag.intents, this.state.intent).size !== 0) }); setTimeout(this.setState({ unselected_tags: data.filter(tag => !this.state.selected_tags.includes(tag))}), 0) } } 可能是一种不好的做法。另一方面,我也没有设法使用setTimeout,因为ComponentDidUpdate()会在我输入时立即更新,因此它不会等待value填充。

我怀疑intents在这种情况下可能会有所帮助,但我没有在网上找到任何真正使用此功能(带有上下文和所有内容)。 是否有等价于getDerivedStateFromProps()的地方,我可以选择等待状态的哪种特定更新?

一般来说,我不确定如何以反应的方式协调我的流程与反应生命周期。

2 个答案:

答案 0 :(得分:0)

一般情况下,不要将派生状态置于React状态。相反,您应该选择为每个渲染生成派生状态。重点是确保您的州始终有效。但是,如果确保它永远无效,那么使用派生状态真的不是什么大问题。

这里的问题是您要更新意图,然后在您应该立即执行此操作时更新派生状态。

只是做:

axios.get('http://localhost:3001', {
    params: {
      text: this.state.value
    }
  })
.then(response => {
    const intent = [....]
    const selected_tags = data.filter(tag => this.checkIntersection(tag.intents, intent).size !== 0)
    cont unselected_tags = data.filter(tag => !selected_tags.includes(tag))

    this.setState({ intent, selected_tags, unselected_tags })
})

答案 1 :(得分:0)

第一个解决方案(未绑定到React)。

编辑。请参阅下面的Kevin Raoofi回答。

第二个解决方案(React)。设置状态具有将在设置状态后将同步调用的回调。代码可以是这样的:

>>>rtc.datetime((2000,1,1,5,0,0,0,0))
>>>rtc.datetime()
(2000,1,1,5,0,0,1,545)

但这感觉就像意大利面......