0

I am trying to calculate some data based on my window size.
Each time we resize the window, I calculate the number of tabs I can put inside my tab bar. I use the hook useWindowSize from react-use for this.

The problem is that the linter is complaining that:
React Hook useEffect has missing dependencies: 'navIndex', 'numberOfChunkedElement', 'tabs', and 'value'. Either include them or remove the dependency array.

The issue is that I can't put value inside the dependency array because it will cause an infinite loop.

Here is my code:

  const [value, setValue] = useState([0, 0]); // [selectedChunckedNavIndex, selectedIndex]
  const [navIndex, setNavIndex] = useState(0);
  const [numberOfChunkedElement, setNumberOfChunkedElement] = useState(0);
  const [chunkedTabs, setChunkedTabs] = useState<TabProps[][]>([[]]);

  /* [...] */

  useEffect(() => {
    // Each time the window is resized we calculate how many tabs wwe can render given the window width
    const padding = 20; // The AppBar padding

    const numberOfTabIcons = navIndex === 0 ? 1 : 2;
    const wrapperWidth =
      wrapper.current.offsetWidth - padding - numberOfTabIcons * 30;
    const flattenIndex = value[0] * numberOfChunkedElement + value[1];
    const newChunkedElementSize = Math.floor(wrapperWidth / 170);

    setNumberOfChunkedElement(newChunkedElementSize);
    setChunkedTabs(chunkArray([...tabs], newChunkedElementSize));
    setValue([
      Math.floor(flattenIndex / newChunkedElementSize),
      flattenIndex % newChunkedElementSize,
    ]);
  }, [width /* , navIndex, numberOfChunkedElement, tabs, value */]);

My question is How can I re-calculate some data and set them inside my component each time the width changes ?

Rémi Doreau
  • 232
  • 2
  • 8
  • You are updating `value` inside `useEffect` hook by calling `setValue`. Putting `value` within deps will cause infinite loop – user0101 Jun 09 '20 at 11:01
  • one question. Will flattenIndex not use `newChunkedElementSize`. Are you sure it has to use the previous size? – Shubham Khatri Jun 09 '20 at 11:11
  • @ShubhamKhatri Yes it has to use the previous size – Rémi Doreau Jun 09 '20 at 11:34
  • you must note that the dependency warning is a way of reminding user that that something might be wrong and not a sure shot error that some thing is wrong. If you are absolutely sure that you only want to update states when width changes and not when say `tabs` changes you can just add width as a dependency and disable the warning. This post covers this in a little more details: https://stackoverflow.com/questions/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook/55854902#55854902 – Shubham Khatri Jun 09 '20 at 11:41
  • If you still think, that you do not want to disable the warning and would like a solution that doesn't warn you about missing dependency please let me know. – Shubham Khatri Jun 09 '20 at 11:43
  • Thanks for your response ! I would have preferred not to have to disable the warning, if you have something else I'll take it. – Rémi Doreau Jun 09 '20 at 11:54
  • It seems that most of your data is derived state. If so, you could use `useMemo` instead: `const tabs = useMemo(()=> {...}, [width, value])` – ford04 Jun 09 '20 at 13:23

0 Answers0