reactjs 如何在eslint中使用useEffect中的prop函数

vecaoik1  于 2023-05-06  发布在  React
关注(0)|答案(5)|浏览(115)

我想在useEffect中调用一个prop函数。下面的代码在没有任何警告的情况下工作:

useEffect(() => {
    props.handleClick(id);
}, [id]);

但是eslint抱怨props不是一个依赖项。
如果我将其作为依赖项添加,代码将不再工作,并且我将获得最大的重新渲染错误:

useEffect(() => {
    props.handleClick(id);
}, [id, props]);

如何解决这个lint问题?

示例代码:

const ParentGrid = ({rows, columns}) => {
    const [selection, setSelection] = useState(null);

    const handleClick = selectedRows => {
        setSelection(selectedRows.map(i => rows[i]));
    };

    return (
        <ChildGrid
            columns={columns}
            data={data}
            handleClick={handleClick} />
    );
}

const ChildGrid = props => {
    const {data, handleClick, ...rest} = props;

    useEffect(() => {
        handleClick(selectedRows);
    }, [selectedRows]);
  
    // ...etc
};
e5nszbig

e5nszbig1#

添加props.handleClick作为依赖项

useEffect(() => {
  props.handleClick(id);
}, [id, props.handleClick]);
puruo6ea

puruo6ea2#

我在这里看到了很多奇怪和不正确的答案,所以我觉得有必要写这个。
将函数添加到依赖数组时达到最大调用深度的原因是它没有稳定的标识。在react中,如果你没有将函数 Package 在useCallback钩子中,那么函数将在每次渲染时重新创建。这将导致react在每次渲染时看到您的函数发生更改,因此每次都调用useEffect函数。
一种解决方案是将函数 Package 在父组件中定义的useCallback中,并将其添加到子组件中的依赖数组中。使用您的示例,这将是:

const ParentGrid = ({rows, columns}) => {
  const [selection, setSelection] = useState(null);

  const handleClick = useCallback((selectedRows) => {
    setSelection(selectedRows.map(i => rows[i]));
  }, [rows]); // setSelection not needed because react guarantees it's stable

  return (
    <ChildGrid
      columns={columns}
      data={data}
      handleClick={handleClick}
    />
  );
}

const ChildGrid = props => {
  const {data, handleClick, ...rest} = props;

  useEffect(() => {
    handleClick(selectedRows);
  }, [selectedRows, handleClick]);
};

(This假设父组件中的rows属性不会在每次渲染时更改)

6jjcrrmo

6jjcrrmo3#

一种正确的方法是添加props.handleClick作为依赖项,并在父项(useCallback)上记住handleClick,这样函数引用就不会在重新呈现之间发生不必要的更改。
通常不建议关闭lint规则,因为它可以帮助处理细微的bug(当前和将来)
在本例中,如果从deps数组中排除handleClick,且在父对象上函数依赖于父对象属性或状态,则当父对象属性或状态发生更改时,useEffect将不会触发,尽管它应该触发,因为handleClick函数现在已经更改。

nnvyjq4y

nnvyjq4y4#

你应该在 prop 外解构handleClick
在组件的开头,您可能会看到这样的内容:
const myComponent = (props) =>
改为
const myComponent = ({ handleClick, id })基本上你可以把你知道的任何 prop 作为它们的实际名称
然后像这样使用:

useEffect(() => {
    handleClick(id);
  }, [id, handleClick]);

或者你可能并不需要函数作为依赖项,所以这应该可以工作

useEffect(() => {
    handleClick(id);
  }, [id]);
gcmastyq

gcmastyq5#

这对我来说很有效(不确定这是否是一个好的做法):

const { current: handleClick } = useRef(props.handleClick)

useEffect(() => {
    handleClick(id)
}, [id, handleClick])

相关问题