Access react-final-form values from outside the form
Asked Answered
A

1

6

I have a react-final-form Form. The component exposes the values field. This field contains all the fields changed inside the form. The issue is, I want to access the values from outside of it.

     <Form onSubmit={onSubmit} render={({handleSubmit,values}) => 
       ...
       {JSON.stringify(values)} <- this works
     </Form>
<div>
{JSON.stringify(values)} <- this is outside, it doesn't work
</div>

I'd like to avoid shoving everything inside the form just to be able to access the values. Is there any way to access it outside or some way to at least pass a values/setValues from the outside to make the values visible outside the Form?

Appellative answered 27/7, 2020 at 14:30 Comment(6)
why do you need it outside the form? You can try and checkout formspy if you want to do some operation on changesElegy
I have multiple components needing the data and it's getting cumbersome to have them inside the form. I suppose I can use formSpy with onchange and have state synced with it at a higher level. The problem is syncing states usually is not a good idea.Appellative
@ArturCarvalho - did you manage to solve this? Having similar problem: #63217105Colonnade
If you don't want to use states for this, would you consider implementing a state reducer like Redux? You could, then, use the values anywhere you want, at any level.Ulphi
@Colonnade Currently I have a messy hook with a useState inside and a useEffect tracking when the state changes. The solution lacks simplicity and it's not easily readable. I should work on that this week and if I'm not sidetracked, I'll post my solution.Appellative
@DavidBuzatu It's not the using states part that is an issue, it's more having dependencies between the internal and external states. My problem is more complex than the one I described in the question but I'm trying to break it apart. I think the clearest solution is still Sujit.Warrier.Appellative
D
5

The simplest way I found to get the form state outside the form is to use a MutableRefObject to get a reference to the form instance that is available inside the form.

Steps to achieve this:

  1. Create a MutableRefObject (it is basically just a ref object whose current value can be changed)
const formRef: React.MutableRefObject<FormApi> = useRef(null);

If you have interfaces for the form, you can add the form interface like this to get typings for the properties we can access through this reference:

const formRef: React.MutableRefObject<FormApi<IForm, Partial<IForm>>> = useRef(null);
  1. Inside the <Form>, attach the form instance to the MutableRefObject we just created:
<Form onSubmit={onSubmitHandler}>
    {({ handleSubmit, submitting, form, dirty }) => {
        // form reference to access for outside
        formRef.current = form;
  1. Now you can use formRef to access all properties described here in Final Form Docs - 'FormAPi' like this:
formRef.current.getFieldState();
formRef.current.change('fieldName',"value");

Explanation:

This method essentially creates a ref object and attaches the form instance to the object, and since it is a MutableRefObject, it can be changed without causing a re-render. Now, the entire form state as well as modifications to the form can be accessed and controlled from anywhere.

Devoir answered 16/8, 2021 at 14:28 Comment(2)
I think this works, but just to be clear you are using Typescript in the first two code snippets which may not be applicable to original question.Septum
Yes, this is in TS, but the same lines without the types would work in JS too right? Or should I edit the answer?Devoir

© 2022 - 2024 — McMap. All rights reserved.