最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Hooks useEffect, adding dependency triggers infinite loop - Stack Overflow

programmeradmin4浏览0评论

Inside of my useEffect, I have a props dependency (setIsValid). When I add this dependency to the useEffect, it lands in an infinite loop.

Parent when Calling Child Component:

const setIsValid = (bool) => {
  const tmpStateCopy = Object.assign({}, state);
  tmpStateCopy.isValid = bool;

  setState(tmpStateCopy);
};

return <Child
  setIsValid={setIsValid}
/>

In the Child Component:

const { setIsValid } = props;

const [state, setState] = useState({
  transformations: [],
  duplicateIndexes: []
});

const { transformations, duplicateIndexes } = state;

useEffect(() => {
  const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
  const hasDuplicates = duplicateIndexes.length > 0;
  const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);

  setIsValid(isValid)

  console.log('got triggered');
}, [state]);

This way the code works but I always get a warning.

What I want is, that the validation is always triggered when one of the values inside the state changes (transformations / duplicateIndexes).

By adding the setIsValid() func from the props, it runs infinitely.

The Warning looks like this:

./src/ponents/UI/integrationBuilder/layoutElements/transformer/modules/ifModules/ifModule.js
  Line 103:  React Hook useEffect has missing dependencies: 'duplicateIndexes.length', 'setIsValid', and 'transformations'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

My question is, how can I keep the same logic without getting this warning?

Inside of my useEffect, I have a props dependency (setIsValid). When I add this dependency to the useEffect, it lands in an infinite loop.

Parent when Calling Child Component:

const setIsValid = (bool) => {
  const tmpStateCopy = Object.assign({}, state);
  tmpStateCopy.isValid = bool;

  setState(tmpStateCopy);
};

return <Child
  setIsValid={setIsValid}
/>

In the Child Component:

const { setIsValid } = props;

const [state, setState] = useState({
  transformations: [],
  duplicateIndexes: []
});

const { transformations, duplicateIndexes } = state;

useEffect(() => {
  const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
  const hasDuplicates = duplicateIndexes.length > 0;
  const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);

  setIsValid(isValid)

  console.log('got triggered');
}, [state]);

This way the code works but I always get a warning.

What I want is, that the validation is always triggered when one of the values inside the state changes (transformations / duplicateIndexes).

By adding the setIsValid() func from the props, it runs infinitely.

The Warning looks like this:

./src/ponents/UI/integrationBuilder/layoutElements/transformer/modules/ifModules/ifModule.js
  Line 103:  React Hook useEffect has missing dependencies: 'duplicateIndexes.length', 'setIsValid', and 'transformations'. Either include them or remove the dependency array  react-hooks/exhaustive-deps

My question is, how can I keep the same logic without getting this warning?

Share Improve this question edited Jun 23, 2019 at 6:47 skyboyer 23.8k7 gold badges62 silver badges71 bronze badges asked Jun 11, 2019 at 12:08 EmreEmre 1531 gold badge2 silver badges10 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

Since, when state changes you will call the effect. transformations and duplicateIndexes will already be considered for. To avoid the warning, you can move the destructure within useEffect

const { setIsValid } = props;

const [state, setState] = useState({
  transformations: [],
  duplicateIndexes: []
});



useEffect(() => {
  const { transformations, duplicateIndexes } = state;
  const invalids = transformations.find(x => (x.value === '' || x.replaceWith === ''));
  const hasDuplicates = duplicateIndexes.length > 0;
  const isValid = ((invalids === undefined) && (transformations.length > 0) && !hasDuplicates);

  setIsValid(isValid)

  console.log('got triggered');
}, [state]);

Also regarding setIsValid as a dependency to useEffect, you must not do that since a new function for it is created on every render and it will cause the useEffect to to run again and again unles you refactor your code a bit.

const setIsValid = useCallback((bool) => {
  setState(prev =>  Object.assign({}, prev, {isValid: bool});
}, []);

and now you can set setIsValid as a dependency.

发布评论

评论列表(0)

  1. 暂无评论