嗨,我正在使用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像状态一样,但是出现了无限循环。
有人可以帮我什么正确的方法吗? :)
答案 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));