javascript - 即使我正在使用 react update add on,react setState 也不会改变状态

标签 javascript reactjs

在阅读了 React 之后,我决定在一个示例项目中测试一些简单的想法。但我很惊讶为什么 setState 没有按预期工作。 setState 不会更改状态,即使我正在使用更新插件。当我将 setState 更改为状态时,它会起作用!我也记录了新的状态对象,它是正确的。我不知道哪里出了问题!我会感谢你的帮助。

import React from 'react';
import update from 'react-addons-update';
class WebFooterSubscription extends React.Component {
    //========================================================
    constructor(props) {
        super(props);
        this.state = {
            formIsValid: false,
            email: {
                value: "",
                focused: false,
                touched: false,
                isValid: false,
                error: "Enter your email"
            },
            mobile: {
                value: "",
                focused: false,
                touched: false,
                isValid: false,
                error: "Enter your mobile"
            }
        };
    }
    //=================================================================
    componentDidUpdate(prevProps, prevState) {}
    //========================================================
    onBlur(event) {
        if ('mobile1' === event.target.id) {
            let newState = { ...this.state,
                mobile: { ...this.state.mobile,
                    value: event.target.value,
                    focused: false,
                    touched: true
                }
            };
            console.log("mobile blur:", JSON.stringify(newState));
            this.setState(newState); // this seems not to work!
        }
        if ('email1' === event.target.id) {
            let newState = update(this.state, {
                email: {
                    value: {
                        $set: event.target.value
                    },
                    touched: {
                        $set: true
                    },
                    focused: {
                        $set: false
                    }
                }
            });
            console.log("email blur:", JSON.stringify(newState));
            this.setState(newState); // this seems not to work!
        }
        this.cmdValidate();
    }
    //========================================================
    onFocus(event) {
        console.log("focus occured");
        if ('mobile1' === event.target.id) {
            let newState = { ...this.state.mobile
            };
            newState.focused = true;
            newState.touched = true;
            this.setState({ ...this.state,
                mobile: newState
            });
        }
        if ('email1' === event.target.id) {
            this.setState({ ...this.state,
                email: { ...this.state.email,
                    touched: true,
                    focused: true
                }
            });
        }
    }
    //========================================================
    cmdValidate() {
        // console.log("length " ,this.state.mobile.value.length);
        if (this.state.mobile.value && this.state.mobile.value.length === 11) {
            this.setState({ ...this.state,
                mobile: { ...this.state.mobile,
                    isValid: true,
                    error: ""
                }
            });
        } else {
            this.setState({ ...this.state,
                mobile: { ...this.state.mobile,
                    isValid: false,
                    error: "Enter your cell phone number correctly"
                }
            });
        }
        if (this.state.email.value) {
            let isValidEmail = true;
            if (isValidEmail) {
                this.setState({ ...this.state,
                    email: { ...this.state.email,
                        isValid: isValidEmail
                    }
                });
            } else {
                this.setState({ ...this.state,
                    email: { ...this.state.email,
                        isValid: false,
                        error: "Your email is not correct"
                    }
                });
            }
        } else {
            this.setState({ ...this.state,
                email: { ...this.state.email,
                    isValid: false,
                    error: "Enter email"
                }
            });
        }
        if (this.state.email.isValid && this.state.mobile.isValid) {
            this.setState({ ...this.state,
                formIsValid: true
            });
        } else {
            this.setState({ ...this.state,
                formIsValid: false
            });
        }
    }
    //========================================================
    onSubmitClick(event) {
        //this.setState({count : this.state.count + 1});
        event.preventDefault();
    }
    render() {
        return (<form name="subscriptionForm" id="subscriptionForm" className="form" method="post">
                                <div className={`form-group ${this.state.email.touched && !this.state.email.isValid ? ' has-danger' : ''}`}>
                                    <div className="col-md-12  ">
                                        <div className="input-group" >
                                            <input id="email1" name="email1" onBlur={(event)=>this.onBlur(event)} onFocus={(event)=>this.onFocus(event)}  className="form-control"  placeholder="email"  type="text" />
                                            <div className="input-group-addon"><img src="assets/images/icons/svg/opened-email-envelope.svg" alt="email" width="24px" height="24px" /></div>
                                        </div>
                                        <div className="help-block" hidden={!this.state.email.focused}>
                                                 {this.state.email.touched && ((this.state.email.error && <span>{this.state.email.error}</span>))}
                                        </div>

                                    </div>
                                </div>
                                <div className={`form-group ${this.state.mobile.touched && !this.state.mobile.isValid ? ' has-danger' : ''}`}>
                                    <div className="col-md-12  ">
                                        <div className="input-group" >
                                            <input id="mobile1" name="mobile1" className="form-control" onBlur={(event)=>this.onBlur(event)}  onFocus={(event)=>this.onFocus(event)}   placeholder="cell phone" type="text" />
                                            <div className="input-group-addon"><img src="assets/images/icons/svg/talking2.svg" alt="cell phone" width="24px" height="24px" /></div>
                                        </div>
                                    </div>
                                </div>
                                <div className="leftButton">
                                    <button type="submit"  onClick={(event)=> this.onSubmitClick(event)}  className="btn btn-primary" >Subscribe</button>
                                </div>
                                    <div>
                                        {JSON.stringify(this.state)}disabled={!this.state.formIsValid}
                                    </div>
                            </form>);
    }
}
export default WebFooterSubscription;

最佳答案

  • setState 是一个异步操作,所以有时当您尝试在设置后立即访问新状态时,您不会获得更新后的状态。
  • 因此,为了在设置后立即访问新状态,您需要通过回调函数访问它,如下所示:-

    this.setState({//在这里你提供新状态},()=>{//你在这里访问它})

    <
  • 在您的情况下,您可以在 onBlur 函数中以这种方式访问​​它。

  onBlur(event){
let newState
        if('mobile1'===event.target.id){
            newState= {...this.state,mobile:{...this.state.mobile ,value:event.target.value, focused:false, touched:true}};
            console.log("mobile blur:" ,JSON.stringify(newState));
         
        }
        if('email1'===event.target.id){
             newState = update(this.state, { email: { value: {$set: event.target.value} ,touched: {$set: true},focused:{$set:false}}   });
            console.log("email blur:" ,JSON.stringify(newState));
        }
        this.setState(newState,()=>{this.cmdValidate()})
        
    }

  • 希望以上解决方案可以解决您的问题..... :)

关于javascript - 即使我正在使用 react update add on,react setState 也不会改变状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43026264/

相关文章:

javascript - NodeJs,api路由返回后异步函数是否完成

javascript - onClick 事件只留下 DOM 数组的最后一项而不是移除目标

javascript - 在Reactcropperjs中将base64转换为文件类型?

reactjs - 如何在 Jest 中模拟react-i18next和i18n.js?

javascript - 将 JSON 转换为 CSV,并让 Headers 成为父级的串联

javascript - 将 Express 应用程序迁移到 NestJS

javascript - 如果我向 npm 模块添加类型,我如何依赖全局类型?

javascript - 如何在 Javascript 中设置表格样式?

javascript - 使用 withRouter 包装的组件测试按钮的状态

javascript - React Styleguidist 开始懒散