user3637804
user3637804

Reputation: 177

Dynamically Generated Checkboxes with Separate States React-Native

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

Answers (3)

Sagar RS
Sagar RS

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

Jeremy
Jeremy

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

Mayank Shukla
Mayank Shukla

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

Related Questions