如何防止使用 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,你应该可以开始了