Search code examples
javascriptreactjsreduxredux-form

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:

  • I have a simple user form (with only one text field for now), it's a react view bound to the state with connect().
  • I call a rest API to fetch the user.
  • When the api call is done, an action is dispatched with the user.
  • A reducer update the store state with the user.
  • I would like to populate/update the form with the retrieved values.

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?


Solution

  • 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" 
      />
    )