嗨,我正在使用 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 是多余的,因为 map 返回一个数组:
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));