question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dynamic form names - Redux form state not updating when changing forms

See original GitHub issue

Are you submitting a bug report or a feature request?

Bug report

What is the current behavior?

I have an application that renders pages, each of which contain forms with dynamically-configured names (by passing the form prop to the Redux form component).

When rendering a page that contains a Redux form for the first time, it successfully initialises the form and stores the form state within the state tree using @@redux-form/INITIALIZE.

When opening subsequent pages (by navigating to them using React Router), the @@redux-form/INITIALIZE action that is generated consistently contains the first form name despite the fact that the new form name is being provided as a prop to the Redux form when the page renders.

The form on the new page will be blank, and will remain blank when attempting to edit any of the fields. All @@redux-form actions (FOCUS, BLUR, etc.) will be targeting the first form even though a different form is visible and being edited.

What is the expected behavior?

Whenever a page is rendered containing a form, the name specified in the form prop should correspond to the meta.form property of the generated @@redux-form/INITIALIZE action, and the form should load containing the data passed in as initialValues. It should be possible to interact the form, and all interactions should trigger Redux Form actions that identify the currently loaded form, and not the first form that was opened after application startup/page refresh.

What’s your environment?

  • Redux Form 6.6.3
  • Windows 7 64-bit
  • Electron 1.6.8
    • Node: >=7.4.0
    • Chromium: >=56.0.2924.87
    • V8: >=5.6.326.50

Other information

The “page” or “view” that gets loaded when navigating is determined by this React component:

export default function MessageDefinitionRouter (props: IMessageDefinitionRouterProps) {
  const {definition, definitionName} = props;

  if (isTxDefinition(definition)) {
    return <TxMessageDefinitionView {...props}
                                    definition={definition}
                                    form={definitionName}
                                    initialValues={definition}/>;
  } else if (isRxDefinition(definition)) {
    return <RxMessageDefinitionView {...props}
                                    definition={definition}
                                    form={definitionName}
                                    initialValues={definition}/>;
  } else {
    throw new TypeError(`Invalid definition: ${definition}`);
  }
}

Here is the code for TxMessageDefinitionView (the one for RxMessageDefinitionView is very similar):

function TxMessageDefinitionView (props: ITxMessageDefinitionViewProps) {
  const {handleSubmit, form} = props as any;
  console.warn(`Loaded definition view with form name: ${form}`);
  return <CoreMessageDefinitionView definitionName={props.definitionName}
                                    fields={getNamedFields(props.definition)}
                                    propertyForms={createTxPropertyForm(props.definition, handleSubmit)}/>;
}

export default reduxForm({enableReinitialize: false, destroyOnUnmount: false})(TxMessageDefinitionView);

On application startup, I select a page containing a form for editing one particular object, with the form named after that object. It loads fine:

select_msg1a0

I then try selecting another page, expecting to see the form populated with the initial values for that object and allowing me to edit it. Instead I see this:

select_msg1ff

Notice that the INITIALIZE action generated when rendering this page contains the original (i.e. wrong) form name (but the correct initial values payload).

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:9
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

46reactions
TAGCcommented, May 5, 2017

I’ve managed to resolve this issue by setting the key prop equal to my definition name that I pass to my redux-form-wrapped component:

  const txProps = {
    definitionName: props.definitionName,
    initialValues: definition,
    form: definitionName,
    key: definitionName // Added this
  };

  if (isTxDefinition(definition)) {
    return <TxMessageDefinitionView {...txProps} pristineDefinition={definition}/>;
  }
  // ...

Setting this means that React will destroy and recreate the redux form each time I navigate to a new definition.

Before this issue is closed, it could be a good idea to add something about this dispatch memoization happening somewhere in the documentation and suggest this workaround in case users need the dispatch actions to update when props change.

Edit

Alternatively, what about a prop that determines whether mapDispatchToProps returns a closure or not?

(dispatch, props) => {
  // ...
  if (props.memoizeDispatch /* true by default */) {
    return () => computedActions
  } else {
    return computedActions
  }
}
2reactions
dirkroordacommented, May 19, 2017

I had the same problem, and the workaround you advised (adding a key prop with the same value as the form prop), solved it also in my case. Many thanks, because I was getting desperate. The confusing thing was that nearly everything else went OK. For example, meta.form is OK, input.value is OK. So it is really unexpected that input.onChange becomes bound to the wrong form after a few react-router navigation actions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Dynamic form names - Redux form state not updating when ...
I have an application that renders pages, each of which contain forms with dynamically-configured names (by passing the form prop to the Redux...
Read more >
Dynamic formName in redux form not working - Stack Overflow
i want to create multiple redux forms with dynamic name according to a variable. I have this code: import { reduxForm, Field, change...
Read more >
Initializing From State - Redux Form
To run this example locally on your machine clone the redux-form repository, then cd redux-form to change to the repo directory, and run...
Read more >
Getting Started - Redux Form
formReducer updates the corresponding state slice,; The state is then passed back to the input. Same goes for any other interaction like filling...
Read more >
Synchronous Validation Example - Redux Form
Notice the reused stateless function component used to render each field. It is important that this not be defined inline (in the render()...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found