React Hook Form: Making append() Asynchronous

Viewed 3400

React Hook Forms provides a method append() on useFieldArray to add more rows to the dynamic fields array.

I'm able to use append(). However, I want to execute another function immediately after calling append(). But that's not happening. Instead, the next function gets called before append() is completed.

How can I change this behavour and ensure that the next function will be called only after append() is completed?

https://react-hook-form.com/api/usefieldarray

In the following example:

onClick={() => {
                    console.log('fields 1', fields)
                    append({
                      item: 
                        {
                          id: 1, 
                          name: 'test'
                        }
                    });
                    console.log('fields 2', fields)

                    }}>

In the above example, the length of fields remains the same. It doesn't increase. How do I resolve this?

1 Answers

Under the hood, append relies on a call to a useState setter (see the source), which means that fields is a useState stateful value and you'll only see the updated value on the next render.

To perform effects in response to state changes, use the useEffect hook. You can read more about it here. In your case, you'd want to do something like

import React, { useEffect } from 'react';
import { useFieldArray } from 'react-hook-form';

const MyComponent = () => {
  const { fields, append } = useFieldArray(...);

  useEffect(() => {
    // this callback will run once on initial render and
    // then again whenever `fields` is updated
    console.log('fields 2', fields);
  }, [fields]);

  return (
    <div>
      <button onClick={() => {
          console.log('fields 1', fields);
          append({ item: { id: 1, name: 'test' } });
        }}>
        Click me
      </button>
    </div>
  );
};

In the above example, the component will print

fields 2 []

on initial render, and then

fields 1 []
fields 2 [{ id: 1, name: 'test' }]

once you click the button to append a new field. If you need to differentiate between initial render and subsequent updates, you can check that the value of fields has changed from its initial value (probably []).

Related