0

Im attempting to return a HOC component from within the hook.

Let's say I have a top level component as...

function Component(props){
  //do something with props;
  return <h1>Hello {props.title}</h1>
}

And a hook which knows some props, and wants to free the user from providing those props

function useHook(){
  //somehow get prop values at runtime(say title)
  const title = //get from API call;
  return (props) => <Component title={title} {...props}/>
}

Any idea why infinite rerendering happens here? Should I be using useCallback?

D.B.K
  • 410
  • 2
  • 15
  • 2
    You haven't provided enough code for us to say why, but there are tons of problems with this code. 1. Function components and hooks should be pure functions: if you have side effects (like an API call) you **must** put them in a `useEffect`. 2. That's not a HOC but if it were why are you mixing those with hooks? 3. It's not clear why you'd need either one here. 4. If you want to provide data at multiple levels of the render tree and you want to use a hook for doing so you'd normally use the [context API](https://reactjs.org/docs/context.html). Please edit your question to provide more detail – Jared Smith Jul 18 '22 at 10:04
  • sideeffects with useEffect is not the concern of this question, HOC is what needs the attention here. The question is as simple as it gets, HOC inside a hook. Wrapper component that returns a transformed version of existing component. – D.B.K Jul 18 '22 at 10:35
  • Why I'd need this? to abstract away the details from the topmost parent component. If data is available here and now inside the hook, why bother creating multiple hooks to refetch the same data and transfer the responsiblity to parent component to fill in the props? too much manual work , dont you think so? – D.B.K Jul 18 '22 at 10:36
  • Context API just adds to the noise. Say I were to return the context containing the data(from API) from this same hook, I'd also have to look up the context inside the final component again. Makes things less functional, and non-intuitive. – D.B.K Jul 18 '22 at 10:37
  • @JaredSmith, I think youre right, perhaps im using an antipattern here. But what would you suggest in a case where a parent component is supposed to contain, say 20 instances of the same component, and this child component, say, has 10 props, 9 out of which needs to be fetched from API calls. I'd like to know how to solve this in a clean way, which also respects DRY – D.B.K Jul 18 '22 at 10:46
  • 1
    "sideeffects with useEffect is not the concern of this question" any time you make a mistake in the code in your question, especially an *obvious* mistake, it raises the question of whether you actually understand what you wrote. "Context API just adds to the noise... I'd also have to look up the context inside the final component again" not true the context API can make for [very elegant solutions](https://stackoverflow.com/questions/68850880/usecontext-not-updating-on-state-change-in-react/68851743#68851743). ... – Jared Smith Jul 18 '22 at 11:23
  • "Why I'd need this? to abstract away the details from the topmost parent component" that's *backwards*, typically you keep your child components that actually render stuff to the DOM simple and keep the state and logic higher up in the React tree in non-presentational components. I would *probably* (just based on your description of it) use context with a custom hook like in the link that fetched the data and call it in the child components. Either way I'm glad you found a solution! – Jared Smith Jul 18 '22 at 11:26

1 Answers1

1

React Hooks return children wrapping component

The Problem was addressed here. useCallback solved the infinite re-render. Looks like the hook was recreating the component upon every run (function reference changes upon every run, though it looks like its the same function).

function useHook(){
  //somehow get prop values at runtime(say title)
  const title = //get from API call;
  return useCallback((props) => <Component title={title} {...props}/>,[title]);
}
D.B.K
  • 410
  • 2
  • 15