mercredi 24 août 2016

Setting a checkbox "check" property in React

I am having a very annoying issue with React and checkboxes. The application I am working with requires a list of checkboxes that represent settings that are persisted in the back-end. There is an option to restore the settings to their original state.

At first, I created a component that has an object like a map of settings. Each setting has a key and a boolean value. Hence:

{
    bubbles: true,
    gregory: false
}

Is to be represented as:

<input type="checkbox" value="bubbles" checked="checked" />
<input type="checkbox" value="gregory" />

Now, it seems React is ignorant about how a checkbox is supposed to work. I don't want to set the checkboxes' values, I want the "checked" property.

Yet, if I try something like this:

<input
    type="checkbox"
    value={setting}
    checked={this.settings[setting]}
    onChange={this.onChangeAction.bind(this)}
/>

I get this warning:

Warning: AwesomeComponent is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: [some useless docs page I read several times to no avail]

So I decided to create another component to wrap each individual checkbox and I got this:

<input
    type="checkbox"
    checked={this.state.checked}
    onChange={this.onChangeAction.bind(this)}
/>

Now the checked is a property present directly in my state.

This yields the same warning, so I tried using defaultChecked:

<input
    type="checkbox"
    defaultChecked={this.state.checked}
    onChange={this.onChangeAction.bind(this)}
/>

Which makes the warning disappear, but now it is unable to reset the checked value to the default one. So I tried playing with the method componentWillReceiveProps, this way I am quite sure my state is correct, this.state.checked is correct and the component renders again.

And it does. But the checkbox remains as it was originally. For now I left that ugly warning and I am using checked. How do I fix this thing so the warning goes away?

I was thinking that perhaps there is a way to force-re-render the component, so it captures the new defaultChecked value and uses it. But I don't know how to do that. Perhaps suppress the warning only for this component? Is that possible? Perhaps there is something else that can be done?




Aucun commentaire:

Enregistrer un commentaire