在变更道具上反应更新组件

时间:2019-11-24 12:56:19

标签: reactjs react-redux react-hooks

嗨,我正在使用React钩子,我在这里构建LogIn组件:

    const [inputs, updateInputs] = useState(
    [
        {
            type: 'email',
            label: 'Email',
            name: 'email',
            value: '',
            error: false
        },
        {
            type: 'password',
            label: 'Password',
            name: 'password',
            value: '',
            error: false
        }
    ]
    );

    const renderInputs = () => {
        const inputsArr: typeof Input = [];

        inputs.map((item, i) => {
            inputsArr.push(
            <Input key={i} type={item.type} label={item.label} name={item.name} error={item.error}
                   onChange={inputOnChange}/>
            );
        });

        return inputsArr;
    };

    const onButtonClick = useCallback(() => {
        const data = {
            email: inputs[0].value,
            password: inputs[1].value
        }

        let newInputs = inputs;

        if(!data.email.length) {
            newInputs[0].error = true;
            updateInputs(newInputs);
            return false;
        }

        dispatch(signIn(data));
        return true;
    }, []);

我需要捕捉点击错误。但是在单击时,组件输入不会更新。我尝试将renderInputs添加到useEffect中,并使renderInputs像状态一样,但是出现了无限循环。

有人可以帮我什么正确的方法吗? :)

1 个答案:

答案 0 :(得分:1)

首先,renderInputs是多余的,因为映射返回一个数组:

const renderInputs = () => inputs.map((item, i) => <Input
       key={i} // index should also not be used as key
       type={item.type}
       label={item.label}
       name={item.name}
       error={item.error}
       onChange={inputOnChange}/>
);

您的onButtonClick正在将useCallback与[]用作第二个参数。因为它永远不会更新,所以它将始终返回相同的值。将inputs放在方括号中或删除useCallback,因为它无论如何都不会提高您的性能(实际上会更慢)。

您也不会更新输入,因为您正在更改输入而不是将它们更新为不可变的(let newInputs = inputs;与以前相同,因此您只是在更改输入并再次保存相同的对象,而useState不会如果浅层引用与以前相同,则更新。)

尝试一下:

let newInputs = [...inputs];

if(!data.email.length) {
     newInputs[0].error = true;
     updateInputs(newInputs);
     return false;
 }

 dispatch(signIn(data));