防止用钩子重新渲染
prevent re render with hooks
我正在处理 table 内的切换按钮状态。当对 api 的请求失败时,我需要 return 一个错误并且无法检查状态改变。
Checked 由来自 api 的特定数据控制。发生的事情是,当 setErrors 组件重新渲染时,我认为这是切换按钮改变的原因。
async function handleStatus(groups, status, id) {
const response = await chengeStatus(groups, status, id);
const { status: state, data, message } = response;
if (state) {
setGroups(data);
return true;
} else {
setErrors({
status: true,
message: message,
});
return false;
}
}
切换按钮:
const columns = [
{
cell: (row) => {
return (
<Switch
checked={row.enable}
handleChange={() => handleStatus(groups, row.enable, row.id)}
></Switch>
);
},
width: "80px",
},
];
错误显示:
return(
{errors.status &&
<Alert
message="Erro"
description={errors.message}
type="error"
showIcon
/>
}
)
通过防止重新渲染来解决这个问题不是一个好主意。
您需要做的是将 checked={row.enable}
更改为 defaultChecked={row.enable}
将默认值传递给并为实际检查状态创建另一个挂钩:
const Switch = ({ defaultChecked, handleChange }) => {
const [checked, setChecked] = useState(defaultChecked);
useEffect(() => {
setChecked(defaultChecked);
}, [defaultChecked]); // Update the state if props change again.
const onToggle = () => {
handleChange(!checked);
setChecked(!checked);
}
return <Comp checked={checked} onToggle={onToggle} />; // TODO show you the idea only
}
因此单击后选中的值将保持不变,直到您重新获取 row
数据。
我想分享解决方案,正如@AllenWong 所说,防止重新渲染,并不是处理这种情况的最佳途径。
对defaultValue的作用有点迷糊,查了一下..
所以,正如 Allen 所说,我将 checked={row.enable} 更改为 defaultValue={row.enable} 并创建了 checked 钩子。
但我不得不控制检查状态有点不同,因为我有多个检查状态要控制。
所以,我在 switch 组件中添加了 name 属性
<Switch
name={row.id}
checked={checked[row.id]}
defaultChecked={row.enable}
handleChange={() => handleStatus(groups, row.enable, row.id)}>
</Switch>
当请求失败时:
const obj = {...checked}
obj[id] = status
setChecked(obj)
我正在处理 table 内的切换按钮状态。当对 api 的请求失败时,我需要 return 一个错误并且无法检查状态改变。
Checked 由来自 api 的特定数据控制。发生的事情是,当 setErrors 组件重新渲染时,我认为这是切换按钮改变的原因。
async function handleStatus(groups, status, id) {
const response = await chengeStatus(groups, status, id);
const { status: state, data, message } = response;
if (state) {
setGroups(data);
return true;
} else {
setErrors({
status: true,
message: message,
});
return false;
}
}
切换按钮:
const columns = [
{
cell: (row) => {
return (
<Switch
checked={row.enable}
handleChange={() => handleStatus(groups, row.enable, row.id)}
></Switch>
);
},
width: "80px",
},
];
错误显示:
return(
{errors.status &&
<Alert
message="Erro"
description={errors.message}
type="error"
showIcon
/>
}
)
通过防止重新渲染来解决这个问题不是一个好主意。
您需要做的是将 checked={row.enable}
更改为 defaultChecked={row.enable}
将默认值传递给并为实际检查状态创建另一个挂钩:
const Switch = ({ defaultChecked, handleChange }) => {
const [checked, setChecked] = useState(defaultChecked);
useEffect(() => {
setChecked(defaultChecked);
}, [defaultChecked]); // Update the state if props change again.
const onToggle = () => {
handleChange(!checked);
setChecked(!checked);
}
return <Comp checked={checked} onToggle={onToggle} />; // TODO show you the idea only
}
因此单击后选中的值将保持不变,直到您重新获取 row
数据。
我想分享解决方案,正如@AllenWong 所说,防止重新渲染,并不是处理这种情况的最佳途径。
对defaultValue的作用有点迷糊,查了一下..
所以,正如 Allen 所说,我将 checked={row.enable} 更改为 defaultValue={row.enable} 并创建了 checked 钩子。
但我不得不控制检查状态有点不同,因为我有多个检查状态要控制。
所以,我在 switch 组件中添加了 name 属性
<Switch
name={row.id}
checked={checked[row.id]}
defaultChecked={row.enable}
handleChange={() => handleStatus(groups, row.enable, row.id)}>
</Switch>
当请求失败时:
const obj = {...checked}
obj[id] = status
setChecked(obj)