Andres
Andres

Reputation: 1012

Is there a way to interact between hook calls within the same react element

Problem

Is there any way to interact somehow between hook calls within the same render call? To have hook that have an access to the same value on each call. For example, is it possible to implement useRandom() hook, that will generate random value and then will return the same value on each call even within the same render cycle.

Possible but not ideal solution

The only solution i have is to wrap component with some context and consume this context on each hook call to interact. But at forces me to create two additional nodes for each component (context to consume and one more context inside to prevent consuming the same context by nested components). I can create HoC/renderProp for that, but this two additional contexts still be there.

Example

context and hook

const InteractContext = React.createContext();

const useRandom = () => {
  const context = useContext(InteractContext);

  if (!context.value) {
    context.value = Math.random();
  }

  return context.value;
}

component using hooks

const MyComponent = () => {
  const random1 = useRandom();
  const random2 = useRandom();

  return (
    // to prevent using this value by nested components
    <InteractContext value={ null }>
      {random1} === {random2}
    </InteractContext>
  );
}

rendering component

render(
  <>
    <InteractContext value={{}}>
      <MyComponent />
    </InteractContext>,
    <InteractContext value={{}}>
      <MyComponent />
    </InteractContext>
  </>,
  document.getElementById('root')
);

Expected result

I expect to see to lines this format:

<some random number> === <the same number>
<another random number> === <the same random number>

here is an example:

0.123456789 === 0.123456789
0.987654321 === 0.987654321

Upvotes: 2

Views: 121

Answers (1)

Jonas Wilms
Jonas Wilms

Reputation: 138267

Closure maybe?

 const useRandomness = () => (r => () => r)(Math.random());

 // inside the component:
  const useRandom = useRandomness();
  useRandom() === useRandom();

Or pass that shared value in:

  const useRandom = v => v;

  // inside the component:
 const random = Math.random();

 useRandom(random) === useRandom(random)

Upvotes: 1

Related Questions