如何防止使用 useState 的 React const 的重新渲染
How to prevent reRender of React const which uses useState
我正在尝试防止在 React 功能组件中重新渲染,但不确定如何实现或实现什么来实现这一点。
阅读建议使用备忘录,但我不明白如何实现它。
props包括'selectAll' (propType=boolean ),onSelected是一个回调函数,我对selected使用了stateHook。
所以,如果调用了'setSelected(newSelects)'方法,就会进入无限的reRender循环;
我在标记的 return 中有一个解决方法,它有效,但我更愿意使用、学习和理解管理 React 的状态。
代码:
function OptimiserTableBody(props) {
const {Id, columns, send, onSelected, selectAll} = props;
const [selected, setSelected] = useState([]);
// Retrieve the data
const resOData = useQuery(o_data_query, {
variables: {
id: id,
use: use
},
fetchPolicy: 'cache-and-network'
});
// Create an array from the retrieved data for the table, this is used to create the table rows
let steps = resOData.data != undefined ? resOData.data.jobO.data : [];
useEffect(() => {
if (selectAll === true) {
let newSelects = steps.map((n) => n.workStepId);
setSelected(newSelects);
}
}, [selectAll])
return (
<TableBody>
{steps.map((step, index) => (
let isItemSelected = isSelected(step.workStepId);
// Workaround
if (selectAll === true)
{
isItemSelected = true;
}
return (
<TableRow ... >
<TableCell key={'select'} padding="checkbox" >
<Checkbox
checked={isItemSelected}
inputProps={{ 'aria-labelledby': step.workStepId }}
style={{color: kbaColors.grey1}}
onClick={(event) => handleClick(event, step.workStepId)}
/>
</TableCell>
</TableRow>
))}
</TableBody>
);
}
export default React.memo(OptimiserTableBody);
谢谢
由于您在每次渲染时 setSelected
,组件都会按照您所说的重新渲染,并进入无限循环。我相信您想根据 selectAll
更新 selected
。您可以在 useEffect
:
中执行此操作
import {useEffect} from 'react'
useEffect(() => {
if(selectAll){
let newSelects = steps.map((n) => n.workStepId);
setSelected(newSelects);
}
}, [selectAll, steps])
通过将 selectAll
赋予依赖项数组,您可以确保仅当 selectAll
更改时此 useEffect
运行s。
更新
我注意到您需要使用 steps
作为状态变量。所以你可以有两个单独的 useEffects
:
const [selected, setSelected] = useState([]);
const [steps, setSteps] = useState([]);
useEffect(() => {
const resOData = useQuery(o_data_query, {
variables: {
id: id,
use: use
},
fetchPolicy: 'cache-and-network'
setSteps(resOData.data != undefined ? resOData.data.jobO.data : [])
}, [] )
空依赖数组确保 useEffect
将 运行 只有一次,当组件安装时。在另一个之前添加这个 useEffect,你应该可以开始了
我正在尝试防止在 React 功能组件中重新渲染,但不确定如何实现或实现什么来实现这一点。 阅读建议使用备忘录,但我不明白如何实现它。
props包括'selectAll' (propType=boolean ),onSelected是一个回调函数,我对selected使用了stateHook。
所以,如果调用了'setSelected(newSelects)'方法,就会进入无限的reRender循环; 我在标记的 return 中有一个解决方法,它有效,但我更愿意使用、学习和理解管理 React 的状态。
代码:
function OptimiserTableBody(props) {
const {Id, columns, send, onSelected, selectAll} = props;
const [selected, setSelected] = useState([]);
// Retrieve the data
const resOData = useQuery(o_data_query, {
variables: {
id: id,
use: use
},
fetchPolicy: 'cache-and-network'
});
// Create an array from the retrieved data for the table, this is used to create the table rows
let steps = resOData.data != undefined ? resOData.data.jobO.data : [];
useEffect(() => {
if (selectAll === true) {
let newSelects = steps.map((n) => n.workStepId);
setSelected(newSelects);
}
}, [selectAll])
return (
<TableBody>
{steps.map((step, index) => (
let isItemSelected = isSelected(step.workStepId);
// Workaround
if (selectAll === true)
{
isItemSelected = true;
}
return (
<TableRow ... >
<TableCell key={'select'} padding="checkbox" >
<Checkbox
checked={isItemSelected}
inputProps={{ 'aria-labelledby': step.workStepId }}
style={{color: kbaColors.grey1}}
onClick={(event) => handleClick(event, step.workStepId)}
/>
</TableCell>
</TableRow>
))}
</TableBody>
);
}
export default React.memo(OptimiserTableBody);
谢谢
由于您在每次渲染时 setSelected
,组件都会按照您所说的重新渲染,并进入无限循环。我相信您想根据 selectAll
更新 selected
。您可以在 useEffect
:
import {useEffect} from 'react'
useEffect(() => {
if(selectAll){
let newSelects = steps.map((n) => n.workStepId);
setSelected(newSelects);
}
}, [selectAll, steps])
通过将 selectAll
赋予依赖项数组,您可以确保仅当 selectAll
更改时此 useEffect
运行s。
更新
我注意到您需要使用 steps
作为状态变量。所以你可以有两个单独的 useEffects
:
const [selected, setSelected] = useState([]);
const [steps, setSteps] = useState([]);
useEffect(() => {
const resOData = useQuery(o_data_query, {
variables: {
id: id,
use: use
},
fetchPolicy: 'cache-and-network'
setSteps(resOData.data != undefined ? resOData.data.jobO.data : [])
}, [] )
空依赖数组确保 useEffect
将 运行 只有一次,当组件安装时。在另一个之前添加这个 useEffect,你应该可以开始了