React Native Elements Checkbox keeps selecting all items instead of the one item this is selected

1.7k Views Asked by At

Hope all is well, and that everyone has a great and safe weekend. I need a little help with this one. I have been stuck on this for a week now. I have a react native project where I am using a flatlist with a react native element checkbox inside of it. I have the flatlist displaying data fetched from my database. So everything works correctly. But when I check one of the items that is being displayed, it checks them all. I have googled and tried several different methods that I got off of here as well. Either nothing is checked or all is checked in the checkbox. Can you guys please take a look at my code below and let me know if I am missing something?

Thank you so much!!!

import React from 'react';
import {
    View,
    Text,
    FlatList,
    StyleSheet, 
} from 'react-native';

import {
    ListItem,
    CheckBox,
} from 'react-native-elements';
import BackButtonMGMT from '../Components/BackButtonMGMT';

export default class ViewCategory extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            dataSource: [],
            checked: false,
        }
    }

    render() {

        const  { navigation } = this.props;
        const cust = navigation.getParam('food', 'No-User');
        const other_param = navigation.getParam('otherParam', 'No-User');
        const cust1 = JSON.parse(cust);
    
        const data = cust1;
        console.log(data);

        return (
            <View style={styles.container}>
                <BackButtonMGMT navigation={this.props.navigation} />

                <FlatList
                    data={data}
                    extraData={this.state}
                    keyExtractor={(item, index) => index.toString()}
                    renderItem={({ item, index }) => (
                        <CheckBox
                        center 
                        titleProps={{ color: 'black', fontWeight: 'bold'}}
                        title={item}
                        iconRight
                        checked={this.state.checked}
                        size={30}
                        onPress={() => this.setState({checked: !this.state.checked})}
                        containerStyle={styles.checkBox}
                        //bottomDivider
                        //chevron
                        />
                        
                    )}
                />

            </View>
        )
    }

    onCheck = (item) => {
        this.setState((state) => ({
            checked: !state.checked,
        }));
    }
}

2

There are 2 best solutions below

7
On

You are currently setting the checkboxes in the list to checked={this.state.checked}

It doesn't look like you're using the onCheck method and instead handling the event in the onPress. So when your onPress event handler fires it is toggling the entire list because each item in the list is using the same state.

Instead you need to keep track of all the items in the array's checked state. You will want to do something like:

this.state = {
  items: [],
  ... // other state
}
...
renderItem={({ item }) => (
  <CheckBox
    checked={!!item.checked} // <-- individual item checked state here
    onPress={() => {
      const items = [...this.state.items] // <-- shallow copy to show we're not mutating state
      const currentItemIndex = items.findIndex(v => v.name === item.name) // <-- lookup by something unique on the item like an ID. It's better to lookup rather than assume the array indexes are ordered the same.
      items[currentItemIndex].checked = !items[currentItemIndex].checked
      this.setState(state => ({ ...state, items }))
    }}
    ... // other props
  />
)}
0
On

This is how I solved it, but now I am not able to select multiple items at a time.

export default class ViewCategory extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            dataSource: [],
            checked: null,
        }
    }

    render() {

        const  { navigation } = this.props;
        const cust = navigation.getParam('food', 'No-User');
        const other_param = navigation.getParam('otherParam', 'No-User');
        const cust1 = JSON.parse(cust);
    
        const data = cust1;
        console.log(data);

        return (
            <View style={styles.container}>
                <BackButtonMGMT navigation={this.props.navigation} />

                <FlatList
                    data={data}
                    extraData={this.state}
                    keyExtractor={(item, index) => index.toString()}
                    renderItem={({ item, index }) => (
                        <CheckBox
                        center 
                        titleProps={{ color: 'black', fontWeight: 'bold'}}
                        title={item}
                        iconRight
                        checked={this.state.checked === item}
                        size={30}
                        onPress={() => this.setState({checked: item})}
                        containerStyle={styles.checkBox}
                        />
                        
                    )}
                />

            </View>
        )
    }