Reputation: 177
I have list of products that are being generated each product has a checkbox associated with it. Right now all of my checkboxes are sharing the same state so when you check one, all of them end up being checked. The product data including the checkbox are in a loop , how can I generate checkboxes with different states? I am using React Native and the checkbox component is using react-native-elements
<View>
{products.map((value, key) => {
return (
<View
key={value.serialNumber + key}
style={localStyles.productCheckbox}
>
<Text key={value._id + key} style={localStyles.modalText}>
{value.pModel}
</Text>
<Text
key={value.pModel + key}
style={localStyles.modalText}
>
{value.serialNumber}
</Text>
<Text
key={value.pVersion + key}
style={localStyles.modalText}
>
{value.versionNumber}
</Text>
<CheckBox
checked={this.state.checked}
onPress={() => {
this.setState({ checked: !this.state.checked });
}}
key={value._id}
/>
</View>
Upvotes: 1
Views: 1930
Reputation: 161
hi recently i also stumbled upon this issue, it seems easy to solve but i took a lot of time to solve it. The below code creates dynamic key-value pairs in state. if you console.log the state in your render you'll see (check0:true check1:true check2: false ....) Hope my solution helps someone.
<Switch
value={this.state[`check${key}`]}
onValueChange={value => this.setState({ [`check${key}`]: value })}
/>
Upvotes: 0
Reputation: 3728
You need to make a dictionary in your state that uses the unique id of the checkbox as a key, and the value will be the checked state.
// setting up your state in the ctor
this.state = { checkboxValues : {} }
<View>
{products.map((value, key) => {
const uniqueKey = value.serialNumber + key; // Unique identifier could probably be just the serial number i presume..
return (
<View
key={uniqueKey}
style={localStyles.productCheckbox}
>
<Text key={value._id + key} style={localStyles.modalText}>
{value.pModel}
</Text>
<Text
key={value.pModel + key}
style={localStyles.modalText}
>
{value.serialNumber}
</Text>
<Text
key={value.pVersion + key}
style={localStyles.modalText}
>
{value.versionNumber}
</Text>
<CheckBox
checked={this.state.checkboxValues[uniqueKey].checked} // read from the state dictionary based on the id
onPress={() => {
// assign a new checked state based on the unique id. You'll also need to do some error/undefined checking here.
const newCheckboxValues = this.state.checkboxValues;
newCheckboxValues[uniqueKey].checked = !newCheckboxValues[uniqueKey].checked
this.setState({ checkboxValues: newCheckboxValues });
}}
key={value._id}
/>
</View>
Upvotes: 1
Reputation: 104379
Instead of using a bool value, use an array that will store the ids of all the checked items.
Like this:
this.state = {
....
checked: [],
....
}
Now for each checkbox check whether its id exists inside array of not:
<CheckBox
checked={this.state.checked.includes(value._id)}
Update the state array inside onPress event handler:
onPress={(e) => this.handleCheckbox(value._id, e)}
handleCheckbox(id, e) {
// check whether item is checked or unchecked on the basis of add and remove
if (/* checked */) {
this.setState((prevstate) => ({
checked: [...prevState.checked, id]
}))
} else {
this.setState((prevstate) => ({
checked: prevState.checked.filter(el => el != id)
}))
}
}
Upvotes: 1