We encounter a case scenario where the useHref Hook will cause the violation of the rule of Hooks. The order of Hooks execution is different between renders. We completely understand that by putting the useHref hook inside a condition or in a loop can cause this violation, however we don't have an answer on how can the following example be achieved without violating this rule of Hooks.
Link to the example => https://codesandbox.io/s/magic-list-rt3ig?file=/src/App.js
In the example you can see that we are generating href links with useHref while mapping a dynamic array of links. As you are adding more links to the array using the provided form, the order of Hooks will be changed between re-renders causing the violation of Hooks.
createHref, used in the useHref Hook, not exported from the library? Using it in such use cases as above would be perfect.useHref Hook? So, that maybe accepts an array of paths? Or even better maybe something like useState Hook, where you have the method to set the state but instead of the state we could have the createHref exposed?Thank you very much for your help.
You should use useHref inside of the components rendered in the loop.
You should use
useHrefinside of the components rendered in the loop.
@pshrmn Great idea.
For example:
const Mapper = ({pathname}) => useHref(pathname);
const Baz = ({list}) => (
<div>
{list.map((item, index) => (
<div key={index}>
<Mapper pathname={item} />
</div>
))}
</div>
);
In other cases, where it is not possible to use a React component (e..g., forwarding data to third party), then the easiest solution is to invalidate the component with the key.
const Baz = ({list}) => (
<div>
{list.map(useHref).map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
);
...
<Baz key={list.length} ... />
Note: use for key any unique value (e.g., uuid, counter++).
Thank you @pshrm & @artola . For our use case changing the key did the trick. No more wrong Hooks order 馃憤
Most helpful comment
@pshrmn Great idea.
For example:
In other cases, where it is not possible to use a React component (e..g., forwarding data to third party), then the easiest solution is to invalidate the component with the key.
Note: use for
keyany unique value (e.g.,uuid,counter++).