Home > Software design >  React hooks: React has detected a change in the order of Hooks called by NodeDetails. / Rendered mor
React hooks: React has detected a change in the order of Hooks called by NodeDetails. / Rendered mor

Time:12-20

I am using a custom <CompositeInput> component which I render inside a list.

      <div className="p-6">
        {nodeProperties.map(({ key, value }) =>
          CompositeInput({
            value: value,
            label: key,
            key: key,
            onChange: editing ? (x) => console.log(x) : undefined,
          })
        )}
        <div className="flex w-full pt-2">{bottomBar}</div>
      </div>

Inside this list I call useState to hold the components input state:

const DataPropertyInput = (
  value: DataPropertyValue,
  onChange?: (newData: DataPropertyValue) => void
) => {
  const [updatedValue, setValue] = useState(value);
  return matchExhaustive(updatedValue, {
    StringWrapper: (string) => (
      <input
        onChange={(ev) => {
          setValue(DataPropertyValue.StringWrapper(ev.target.value));
          onChange?.(DataPropertyValue.StringWrapper(ev.target.value));
        }}
        disabled={!onChange}
        className="p-1 bg-transparent mr-2"
        value={string}
      />
    ),
    DateTimeWrapper: (strData) => <div> "datepicker"</div>,
    Unknown: () => <div> Special property type </div>,
    IntWrapper: (int) => <div> NUMBER INPUT </div>,
    EmptyWrapper: () => <div>Empty </div>,
    ManyOfMany: () => <div>Dropdown here </div>,
  });
};

Obviously the number of hooks called changes when I add another nodeProperty.

What is the right way to use React useState so that it does not complain?

error

CodePudding user response:

One of the hooks rules is to : Ensure that the hooks are always called the same number of times for a given component.

I think the issue arises because you are calling as function (), instead of a component. Now, the hooks inside the CompositeInput are associated with its parents component.

Change that and see:

{nodeProperties.map(({ key, value }) =>
          <CompositeInput 
            value={value}
            label={key}
            key={key}
            onChange={editing ? (x) => console.log(x) : undefined} />
  
        )}

Read more

  • Related