'How to create a custom hook that recives dependencies?

I'm making a custom hook that have a toogle when some state change.

You should be able to pass any state in an array.

import { useState, useEffect } from 'react'

const useFlatListUpdate = (dependencies = []) => {
    const [toggle, setToggle] = useState(false)

    useEffect(() => {
        setToggle(t => !t)
    }, [...dependencies])

    return toggle
}

export default useFlatListUpdate

And it should be used as

const toggleFlatList = useFlatListUpdate([search, selectedField /*, anything */])

But it gives me the following warning

React Hook useEffect has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies.eslint(react-hooks/exhaustive-deps)

I also have another situation where it doesn't work

const useFlatListUpdate = (dependencies = []) => {
    const [toggle, setToggle] = useState(false)

    useEffect(() => {
        setToggle(t => !t)
    }, dependencies)

    return toggle
}

This gives me the warning

React Hook useEffect was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.eslint(react-hooks/exhaustive-deps)

How can I make this work without the warning and without disabling eslint?



Solution 1:[1]

Use of dependency list is very peculiar in this case.
I do not see other way except ignoring or silencing the warning.

To silence the warning, we do not have to disable eslint completely.
You can disable this specific rule for this specific line:

const useFlatListUpdate = (dependencies = []) => {
    const [toggle, setToggle] = useState(false)

    /* eslint-disable react-hooks/exhaustive-deps */
    useEffect(() => {
        setToggle(t => !t)
    }, [...dependencies])

    return toggle
}

Solution 2:[2]

Do you really need to create a custom hook as per the question.

You can use useEffect to check whether your dependency has changed or not if it is changed set the toggle something like this in your component.

const [toggle, setToggle] = useState(false);
useEffect(() =>{
  setToggle(!toggle);
}, [yourDepndency]);

Help me to understand if I have understood your requirement correctly.

Solution 3:[3]

In the first situation, you are asked to avoid array spreading, So you should just pass the dependancyList as a whole :

    useEffect(() => {
        setToggle(t => !t)
    }, dependencies)

The next warning says that you miss a dependancy (setToggle).

You can use a useCallback with the inner effect dependancies, and then wrap it in the useEffect with the hook-user provided dependancies:

import { useCallback, useState, useEffect } from 'react'

const useFlatListUpdate = (dependencies = []) => {
    const [toggle, setToggle] = useState(false)

    useCallback(() => { setToggle(t => !t) }, [setToggle])
    useEffect(toggleEffect, dependencies])

    return toggle
}

export default useFlatListUpdate

Solution 4:[4]

just keep my record here, sometime i'll forget too

const useCustomHook = (props, deps) => {
    const value = useMemo(()=> props.value, deps)
    return {value}
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ckedar
Solution 2 Seeta Ram Yadav
Solution 3 long-lazuli
Solution 4 Eric