I am trying to implement the drag-n-drop feature on a nested array of inputs. I am using react-beautiful-dnd
and react-hook-form
libraries: useFieldArray
hook to manage the form and useController
hook for controlled input.
The problem I am facing is when i try to reorder any child input, change happens in the last item only. here is a sandbox.
To reproduce the issue, you need to add at least 2 top-level inputs along with 2 nested inputs for each of those. Next try to reorder the nested inputs of the 1st top-level item. As a result, child inputs of the 2nd item would change their positions, while the initially dragged inputs would revert back to their original position.
I tried to pass ref
to nested inputs and used useImperativeHandle
hook to expose move
method of useFieldArray
hook from child component to reorder. But everytime only the last child gets reordered
SOLVED
I was using the same ref for my nested field array to store reorder child function therefore when appending a new nested child field array, it was overriding the reorder function and only moving items belonging to the last nested field array.
To solve this, I had to pass a function instead of ref
to the nested fields which creates different ref
for each
function Parent () {
const childrenRef = useRef({});
const setReorder = useCallback(
(index, reorderCallback) => {
childrenRef.current[index] = reorderCallback;
},
[childrenRef]
);
...
return (
<Child
setReorder={setReorder}
/>
)
}
function Child ({ setReorder, nestIndex }) {
useEffect(() => {
setReorder(`child-${nestIndex}`, (from, to) => {
move(from, to);
});
}, [nestIndex, setReorder, move]);
}
Here is the working sandbox