ReactJS setState 与 getDerivedStateFromProps 冲突 [英] ReactJS setState conflicts with getDerivedStateFromProps

查看:94
本文介绍了ReactJS setState 与 getDerivedStateFromProps 冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试遵循 https://github.com/reactjs/中的设计模式rfcs/issues/26(请参阅 bvaughn 的回复)并创建 ReactJS 可编辑表单,该表单从服务器读取数据,然后在表单字段中显示,允许使用编辑值,然后将这些数据保存回数据库中.

I am trying to follow the design pattern in https://github.com/reactjs/rfcs/issues/26 (see replies by bvaughn) and create ReactJS editable form, that reads data from the server, show then in the form fields, allows the use to edit values and then save those data back in database.

我有一些基本代码:

const mapStateToProps = state => {
    return {
        invoice: state.invoice,
        invoiceReady: state.invoiceReady,
    };
};

 static getDerivedStateFromProps(nextProps, prevState) {
        if (nextProps.match.params.id !== prevState.id) {
            return update(
                prevState, {
                    ['id']: {$set: nextProps.match.params.id},
                    ['invoiceReady']: {$set: false}
                });
        } else {
            return update(
                prevState, {
                    ['invoice']: {$set: nextProps.invoice},
                    ['invoiceReady']: {$set: nextProps.invoiceReady}
                });
        }
    }

 handleChange(event) {
        const state = update(
            this.state, {
                invoice: {
                    [event.target.id]: {$set: event.target.value}
                }
            }
        );
        this.setState(state);
    }

componentDidMount() {
        this.requestInvoice();
    }

componentDidUpdate(prevProps, prevState) {
        if (!this.state.invoiceReady) {
            this.requestInvoice();
        }
    }

并且我的 JSX 代码包含可编辑的字段,例如:

and my JSX code contains editable fields like:

                        <input
                            type="text"
                            className="form-control"
                            id="invoiceDate"
                            value={this.state.invoice.invoiceDate}
                            onChange={this.handleChange}
                        />

所以 - 根据提到的模式,我通过 requestInvoice 向服务器发起请求,其他一些组件处理这个动作并接收发票并将其保存到 Redux 存储中,这就是为什么这些数据被自动写入 props.invoice 变量,我通过 getDerivedStateFromProps<进一步将 props.invoice 写入 this.state.invoice/code> 用于进一步本地处理发票数据.在使用表单的过程中,会引发 handleChange 事件,并在 immutability-helper(更新函数)的帮助下将更新的字段写入新状态并调用 setState.

So - according to the mentioned pattern I am initiating the request to the server by requestInvoice, some other components handle this action and receives and saves the invoice into the Redux store and that is why those data are automatically written into the props.invoice variable and I am further writing props.invoice into this.state.invoice by getDerivedStateFromProps for further local processing of the invoice data. During the work with the form the handleChange events are raised and with the help of immutability-helper (update function) the updated fields are written into new state and setState is called.

我的问题是,在 setState 调用期间,React 正在调用 getDerivedStateFromProps,因此 props.invoice 会覆盖来自用户和那个被处理成 handleChange:setState 函数.

My problem is that during the setState call the React is calling getDerivedStateFromProps and so the props.invoice overwrites any changes that are coming from the user and that ar processed into handleChange:setState function.

那么 - 如何解决这个问题:setStategetDerivedStateFromProps 之间的冲突?

So - how to solve this problem: the conflict between setState and getDerivedStateFromProps?

几个选项可能是:

  • 我的设计可能有缺陷.例如.也许我不应该尝试将 props.invoice 移动到 this.state.invoice (为什么不呢?)?但另一方面,最好将发票保存到 this.state 中,并确保在编辑发票期间将所有更改应用于 this.state.invoice.
  • 我应该在 setState 期间阻止执行 getDerivedStateFromProps 吗?
  • my design can be flawed. E.g. maybe I should not try to move props.invoice into this.state.invoice (why not?)? But from the other side it would be nice to save invoice into this.state and be sure that all the changes are applied to the this.state.invoice during the editing of the invoice.
  • mybe I should prevent execution of getDerivedStateFromProps during setState?

也许其他一些设计模式或代码更适合我的 ReactJS 表单?

Maybe some other design pattern or code is more suitable for my ReactJS form?

我使用的是 ReactJ 16.x

I am using ReactJ 16.x

推荐答案

我得到了以下解决方案 - 在 this.state.stateUpdate 变量的帮助下 - 我认为这是答案对我的问题(如果这不是合理且简洁的解决方案,请发表评论,如果可行,我也可以接受其他答案):

I have arrived at the following solution - with the help of this.state.stateUpdate variable - and I consider this as the answer to my question (please comment if this is not sound and neat solution, I can accept other answer as well if that works):

 const mapStateToProps = state => {
        return {
            invoice: state.invoice,
            invoiceReady: state.invoiceReady,
            stateUpdate: false 
        };
    };

     static getDerivedStateFromProps(nextProps, prevState) {
            if (prevState.stateUpdate) {
              return update(
                prevState, {
                    stateUpdate: {$set: false}
                }
              )
            }
            if (nextProps.match.params.id !== prevState.id) {
                return update(
                    prevState, {
                        ['id']: {$set: nextProps.match.params.id},
                        ['invoiceReady']: {$set: false}
                    });
            } else {
                return update(
                    prevState, {
                        ['invoice']: {$set: nextProps.invoice},
                        ['invoiceReady']: {$set: nextProps.invoiceReady}
                    });
            }
        }

     handleChange(event) {
            const state = update(
                this.state, {
                    invoice: {
                        [event.target.id]: {$set: event.target.value}
                    },
                    stateUpdate: {$set: true}
                }
            );
            this.setState(state);
        }

    componentDidMount() {
            this.requestInvoice();
        }

    componentDidUpdate(prevProps, prevState) {
            if (!this.state.invoiceReady) {
                this.requestInvoice();
            }
        }

这篇关于ReactJS setState 与 getDerivedStateFromProps 冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆