0

I've made a custom react hook useMyElement that returns a JSX.Element and some value, i.e.

interface HookOutput {
  element: JSX.Element;
  value: any;
}

This works just fine but now I want to use a list of those elements and values, i.e.

const hookElements = listOfArgs.map(args => useMyElement(args))

but I realize that this is gives unintended usage. I also get the following warning

React Hook "useMyElement" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function. (react-hooks/rules-of-hooks)

How can I achieve a pattern like this? I.e. want to create a list of react components and return their stateful values from it as well without using something like redux.

4
  • But then first wouldn't be available for use but I guess that would be alright. I disagree with "don't use hooks inside hooks" tho. You'd always use hooks inside hooks, that's almost the reason for having hooks. Commented Feb 4, 2020 at 10:10
  • What is the larger goal here? There could be workable ways of achieving that while obeying the hook rules. Commented Feb 4, 2020 at 11:03
  • The larger goal is my last sentence: " I.e. want to create a list of react components and return their stateful values from it as well without using something like redux." Commented Feb 4, 2020 at 11:40
  • Related: Array of hooks in React Commented Jul 5, 2024 at 23:47

1 Answer 1

2

In this case, firstly, I would make a small change in the 'useMyElement' hook. The interface for HookOutput would look like this:

interface HookOutput {
    elements: JSX.Element[];
    values: any[];
  }

The hook will expose the array of elements and its corresponding values instead of exposing single element and its value.

Now, the hook would look something like this:

const useMyElements = (args: any[]): HookOutput => {
    const [elements, setElements] = useState<JSX.Element[]>([]);
    const [values, setValues] = useState<any[]>([]);

    useEffect(() => {
        args.map(arg => {
            // initialize elements and values
        })
    }, [])

    return {
        elements,
        values
    }
}

I was not sure about the type of args that you would be providing, so, its upto you to initialize the list of elements from the args.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.