Julien Sanchez
Julien Sanchez

Reputation: 841

How to update a field value after action dispatched with redux

I would like to populate a form after an ajax call with redux.

My case is pretty simple:

Solution 1:

If I set the value from the props like that:

const Field = ({ field, onFieldChange, value }) => (
  <input 
    value={value} 
    onChange={(event) => { onFieldChange(field, event.target.value) }} 
    type="text" 
  />
)

It works but I get this warning:

Field is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa).

I understand why I get this error as I should not use a component to display something and also be able to update it.

I also tried to use the defaultValue props but this is only used at the component creation (and we don't have the user yet). After the ajax call return, defaultValue cannot be called.

Solution 2:

Use redux-form with a custom plugin to update the form model each time the state get updated. I don't find this solution really clean but maybe I'm wrong.

I really thin that I'm going in the wrong direction and that it should exist a better way.

Does somebody already faced this kind of issue?

Upvotes: 3

Views: 2667

Answers (2)

kitos
kitos

Reputation: 103

  1. Actually you might try to make your component statefull - store and manage value of input inside of it (they say it's ok).
  2. Or if you really need this value in the store use redux-form, I have realy good experience of using it (you'll have to write less boilerplate code). By the way, you will not have to use any custom plugin, you can use initialValues, see more here

The solution above will work for sure, but it doesn't seem to be nice.

Upvotes: 1

just-boris
just-boris

Reputation: 9776

I encountered the same problem when I was trying to pass undefined as the input value.

To fix this, ensure that you are passing at least empty string to the input, not undefined

const Field = ({ field, onFieldChange, value }) => (
  <input 
    value={value || ''} // <- add fallback value here
    onChange={(event) => { onFieldChange(field, event.target.value) }} 
    type="text" 
  />
)

Upvotes: 2

Related Questions