I created a very simple yes / no component mapped to true / false values with redux form. When clicking "No" the value is updated in the store, but the component does not update. Only after clicking Yes first the component updates when clicking No.
What am I doing wrong here ? why is the state in the store not reflected in the component ?
Note that it's important for my use case that initially, no button is clicked.
sandbox:
https://codesandbox.io/s/r06VKjB4K
import React from 'react';
import { Field, reduxForm } from 'redux-form';
const buttonStyle = {
width: '50px',
display: 'inline-block',
border: '1px solid green',
margin: '5px',
padding: '5px',
cursor: 'pointer',
textAlign: 'center',
};
const ButtonBar = ({ options, input }) =>
<div style={{ display: 'block' }}>
{options.map(x =>
<div
onClick={() => {
input.onChange(x.value);
}}
style={{
...buttonStyle,
...{
backgroundColor: input.value === x.value ? x.selected : 'white',
},
}}
>
{x.displayName}
</div>,
)}
</div>;
const SimpleForm = props => {
return (
<form>
<div style={{ display: 'inline-block', border: '1px solid grey' }}>
<Field
name="myButton"
component={ButtonBar}
options={[
{
value: true,
displayName: 'Yes',
selected: 'green',
},
{
value: false,
displayName: 'No',
selected: 'red',
},
]}
/>
</div>
</form>
);
};
export default reduxForm({
form: 'simple', // a unique identifier for this form
})(SimpleForm);
IDK exactly how redux-form works but you are having some issues regarding undefined initial state and false values; Using format
you can handle that
https://codesandbox.io/s/BL50OzNZY
format={(value) => value}
Just returns the value, no additional checks necessary.
I think the reason is that somewhere in the redux-form code, it treats the empty string and false as the same thing initially and does not trigger a rerender. It looks like redux-form uses this deepEquals function customizer:
const customizer = (obj, other) => {
if (obj === other) return true
if (
(obj == null || obj === '' || obj === false) &&
(other == null || other === '' || other === false)
)
return true
if (obj && other && obj._error !== other._error) return false
if (obj && other && obj._warning !== other._warning) return false
}
You could try setting the initial value to false yourself to see if it fixes your problem.
It is happening because your Field "myButton" has initial state equal to "" and when you click on the "No" button the state changes to false but since the new state equals to the previous one("" == false) the component does not re-render.
You can fix this issue passing some initial state for your component which is different from you options(true and false). For example you can set the initial state as any string:
<SimpleForm
initialValues={{ myButton: 'notTrueOrFalse' }}
onSubmit={showResults}
/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.