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?
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} />
)}