I'm facing an issue where the fields from useFieldArray (react-form-hook) don't get updated when they are replaced from a useEffect hook.
Here's a minimal example that demonstrates it. MyComponent creates a field array using a control provided from its parent component. The field array doesn't get updated and the items don't get rendered the first time (it does in subsequent renders)
const MyComponent = ({ control, items }) => {
const { fields, append, remove, replace, update } = useFieldArray({
control,
name: "items",
});
useEffect(() => {
replace(items)
}, [items]);
return (
<>
{fields.map((item, index) => (
<p key={item.id}>{item.name}</p>
)}
</>)
This component is inside a parent
const [items, setItems] = useState([])
const { handleSubmit, control, setValue, getValues, reset, watch } = useForm({
defaultValues
});
useEffect(() => {
...
// items is a list of {id: '', name: ''} objects
setItems(items);
}, [])
...
return (
<form onSubmit={handleSubmit(saveData)}>
<Controller ... > <TextField ... /> </Controller>
<MyComponent items={items} control={control} getValues={getValues}/>
</>
)
items always has items (not empty).
What I think happening is that fields doesn't get updated at the same time when replace(items) is done and due to some (timing?) issue it is always empty.
Any idea what could be happening and how to avoid it?
Sample code: https://codesandbox.io/s/react-hook-form-usefieldarray-template-forked-2ll8zb?file=/src/index.js:0-1013
The UI basically creates a field array using useFieldArray which receives the Controller from a parent component. The field array is rendered and the purpose is to add/remove items dynamically and reflect the changes on screen. Add/remove functionality is not implemented -- the issue occurs in the first render.
itemsalways has items (not empty)" -itemsis an empty array on the initial render. Also,setItems(items);seems a bit useless unless this is a differentitemsreference. Think you could edit the post to include a more complete minimal reproducible example so we can see whatdefaultValuesis and anything else that wasn't included enough that someone could reproduce this on their end?react-hook-formand thisuseFieldArrayhook, but in your sandbox even when doing a double-append (append the same data twice), and/or looping theitemsarray twice... thefieldsarray still only has length 1 and has the last item added. I did the same bit with a thirditemsarray element added, and only the finalitemselement is appended. I don't think this is a React hooks or component lifecycle issue. If I do a force rerender, again only the final element is appended, but now it's a duplicate entry.useFieldArrayin a child component with the controller being passed from the parent