【问题标题】:ReactJS - State object property is null after setStateReactJS - setState 后状态对象属性为空
【发布时间】:2018-03-31 00:04:01
【问题描述】:

我对 React 比较陌生,我正在用它构建一个新的应用程序。我现在的主要问题是我有一个具有某些属性的状态。基于onchange 属性,我更改了状态属性。之后,当我提交表单时,我尝试将一个对象分配给状态中的一个特定属性,我将从数组上的 find 方法收到该属性。

所以我有一个状态。我复制了这个。之后,我执行find 方法并将从中获得的对象存储在一个变量中。然后我将该对象分配给我所在州的特定属性(冰淇淋)。最后,我用我的新状态 (NewState) 设置状态。

主要问题是在提交表单后,我分配对象的属性(冰淇淋)返回 null。真的很奇怪,因为如果我只使用 newState 变量的变量执行console.log,它将返回一个对象而不是 null。当我console.log返回null的状态时,表单也会以null的属性提交。我的 React 开发工具说属性(冰淇淋)实际上是填充的,而不是空的。

我的代码

constructor(props) {
    super(props);

    this.state = {
        Order: {
            quantity: null,
            name: '',
            email: '',
            icecream_id: 1,
            icecream: null
        }
    }

    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleInput = this.handleInput.bind(this);
    this.getIcecream = this.getIcecream.bind(this);

}

handleInput(key, e) {
    //Get a copy of the current state
    var state = Object.assign({}, this.state.Order);

    //apply for each key the new value
    state[key] = e.target.value;

    //Set the state by the new changes
    this.setState({ Order: state });
}

getIcecream(e) {

    e.preventDefault();

    //Get another copy of the new state
    var newState = Object.assign({}, this.state.Order);

    ///Find the icecream object based on the selected icecream
    var object = this.props.icecreams.find((item) => item.id == this.state.Order.icecream_id);

    //Set the icecream with the founded object
    newState.icecream = object;

    //Set the new state
    this.setState({ Order: newState });

    console.log(newState);
    console.log(this.state.Order);

}

handleSubmit() {

    if (isNaN(this.state.Order.quantity)) {

        alert('Quantity is not a number');

    } else {

        this.props.addOrder(this.state.Order);

        this.setState({ Order: { name: '', email: '', quantity: 0, icecream_id: 0, icecream: null } });

        //this will work for now
        this.props.history.push('/home/orders');


     }

}

HTML/JSX

    <form onSubmit={this.getIcecream}>

        <div className="card card-default">
            <div className="card-header">Add a custom order</div>

            <div className="card-body table-responsive">

                <div className="form-row">
                    <div className="col">
                        <label>Name customer</label>
                        <input type="text" className="form-control" placeholder="Name customer" onChange={(e) => this.handleInput('name', e)} required />
                    </div>
                    <div className="col">
                        <label>E-mail customer</label>
                        <input type="email" className="form-control" placeholder="E-mail customer" onChange={(e) => this.handleInput('email', e)} required />
                    </div>
                </div>

                <div className="form-row mt-3">
                    <div className="col">
                        <label>Quantity (liters)</label>
                        <input type="number" className="form-control" placeholder="1" min="1" onChange={(e) => this.handleInput('quantity', e)} required />
                    </div>
                    <div className="col">
                        <label>Select icecream</label>
                        <select className="form-control" value={this.state.Order.icecream_id} onChange={(e) => this.handleInput('icecream_id', e)}>

                            {this.props.icecreams.map((item) => {
                                return <option value={item.id} key={item.id}>{item.title} ({item.id})</option>
                            })}
                        </select>
                    </div>
                </div>

            </div>
        </div>

        <button type="submit" className="custom-button mt-20">Add order</button>

    </form>

控制台日志

我有什么遗漏吗?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    函数 setState 是异步的。如果你不知道这意味着什么,基本上它要求js做一些事情,但我们真的不知道什么时候会做。但是,js 仍然运行下一部分代码。所以当你这样做时

    this.setState({ Order: newState });
    
    console.log(newState);
    console.log(this.state.Order);
    

    this.state.Order 尚未更改。但是,setState 是重载的,您可以使用 2 个这样的参数调用它

    this.setState({ Order: newState }, 
        ()=>{console.log(this.state.Order}
    );
    

    这确保控制台日志在 setState 之后完成。

    【讨论】:

    • 好的,我去看看。我已经认为它是这样的,所以我正在考虑使用承诺或其他东西。
    • 您的状态现在应该没问题,无需更改。由于 setState 的异步特性,只有 console.log 会让你失望。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2018-08-21
    • 2020-11-25
    相关资源
    最近更新 更多