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);
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.