React |当多个孩子同时向父母发送事件时如何更新父母状态

时间:2021-07-25 04:22:17

标签: javascript reactjs forms validation

我有表单和输入组件。表单包含输入作为子项。每当表单提交时,我都会向子 Input 组件发送一个递增的值。在 Input 组件中,我在该递增值上有一个侦听器 (useEffect) 来验证输入。验证输入后,我正在调用一个函数 onValidation(isValid),该函数作为道具从父级接收。并尝试使用验证结果更新父组件。但是,当表单提交时,所有子组件都会同时调用 onValidation 方法,并且父组件会立即设置状态。因为反应 setstate 不会立即影响验证数据在父级中设置不正确。这是代码。

有没有办法解决这个问题?如果不是,这些用例的最佳模式是什么?


function Form() {
    const [validations,setValidations] = useState({})

    function onValidation(isValid,key) {
        setValidations({...validations,...{[key]:isValid}});
    }

    function onSubmit(){
        //Here the validations object not containing all the input fields data.
        // because while doing setValidation some data is missing
        let isValid = Object.keys(validations).reduce((prev,curKey)=>{return (prev && validations[curKey]) },true);
        if(isValid) {
            window.alert("The form is valid");
        }else {
            window.alert("The form is not valid");
        }
    }

    return (
        <form onSubmit={onSubmit}>
            <Input name="first" onValidation={onValidation}/>
            <Input name="second" onValidation={onValidation}/>
            <Input name="third" onValidation={onValidation}/>
            <Input name="fourth" onValidation={onValidation}/>
        </form>
    )
}

function Input(value,name,onValidation) {
    function validate(e) {
        var val = e.target.value;
        if(val){
            onValidation(true,name)
        }else {
            onValidation(false,name)
        }
    }

    return (
        <input type="text" onChange={validate} value={value}>
    )
}

2 个答案:

答案 0 :(得分:0)

只需将初始状态添加到 validationshttps://codesandbox.io/s/cocky-snowflake-g2rr5?file=/src/App.js

你的初始键是空对象,所以没有一个道具是假的,因此验证没问题

更新

我现在明白是什么让你烦恼了。请阅读this answer

答案 1 :(得分:0)

稍加挖掘后找到了解决此问题的方法。

https://reactjs.org/docs/faq-state.html#what-is-the-difference-between-passing-an-object-or-a-function-in-setstate

当使用 setValidations 设置验证时,我们必须使用回调函数来设置它,而不是直接设置它。通过这种方式,状态设置正确。相应地更新了代码沙箱。

    setValidations((validations) => {
      return { ...validations, ...{ [key]: isValid } };
    });

https://codesandbox.io/s/serene-hofstadter-4nqr3?file=/src/App.js