I am building a SPA using React. I have different forms on different routes. I am using Redux Form for building & maintaining the state of the form. I have components and most of them have a form. In reduxForm()
I am using the form
property to provide a unique name to form. Here is a code of a form.
export default compose(
connect(mapStateToProps, mapDispatchToProps),
reduxForm({ form: 'doctor' })
)(Doctor);
I had around 3 forms at moment with a different value for form
property for different components.
Here is my code for root reducer
import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';
import { USER_LOGOUT } from '../actions/types';
import auth from './auth';
import doctor from './doctor';
import patient from './patient';
import consultation from './consultation';
const appReducer = combineReducers({
auth,
doctor,
patient,
consultation,
form: formReducer
});
Now if I use such code then the routing does not work properly. As I click on the first form following warning is thrown.
However, as soon as I switch to another form in my route then the React throws the following error in console and screen becomes blank.
It is also interesting to notice that the prop
form
of the second form component props does not change. Its registered fields remain the same as that of the previous form.
However, If I change the name of the property in my root reducers from form: formReducer
to something say forms: formReducer
then routing work perfectly but I am not able to change the value of any input in the form, in other words, the state is not bound to the input. So, basically what I get that there is some issue with ReduxForm
. It is also noticed that now we have two props form
and forms
. In form
you get the name of the selected form and in forms
you get its fields.
Here is the code of my index.js
file in case you need it.
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<AppContainer>
<Route path="/" exact component={Welcome} />
<Route path="/signup" component={Signup} />
<Route path="/dashboard" component={App} />
<Route path="/patientreg" component={Patient} />
<Route path="/doctorreg" component={Doctor} />
<Route path="/consultation" component={Consultation} />
<Route path="/signout" component={Signout} />
<Route path="/signin" component={Signin} />
</AppContainer>
</BrowserRouter>
</Provider>,
document.querySelector('#root')
);
I will really appreciate if you help me to figure out the issue. I am stuck at the moment. I have spent a quite long time researching the cause and had gone through various forums & SO post but of no use.
Here are some links I have gone through which can be useful to you
Finally, after wasting hours I found out the answer. The reason for I was getting a blank screen was due to Object Object
in form
field of the props. Due to this, there is a problem in unmounting the component. This happens because the arguments are passed in the wrong order in compose()
. As the FAQ (How do I mapStateToProps or mapDispatchToProps?) of redux form clearly shows that you first need to apply connect()
& then you should pass the modified component to reduxForm()
So I just updated my last line of the component as
export default compose(
reduxForm({ form: 'doctor', key: 'doctor' }),
connect(mapStateToProps, mapDispatchToProps)
)(Doctor);
Note that I also included key prop
that is because in future I want to initialize my form with some prefetch values from the api which should happen properly. Kindly see the issue Dynamic form names - Redux form state not updating when changing forms
Caution
I still had to figure what will happen when I initialize the form with initial value because of the given issue (Get InitialValues by connecting mapStateToProps) in redux form repo on github. Here the order of arguments connect()
& reduxForm()
in the compose()
is reversed. I will update once I reach that section.