Флажок React Native Elements сохраняет выбор всех элементов вместо одного выбранного элемента

#javascript #react-native #checkbox #react-native-flatlist #react-native-elements

#javascript #react-native #флажок #реагировать-native-flatlist #реагировать на собственные элементы

Вопрос:

Надеюсь, все хорошо, и у всех отличные и безопасные выходные. Мне нужна небольшая помощь с этим. Я застрял на этом уже неделю. У меня есть проект react native, в котором я использую плоский список с флажком react native element внутри него. У меня есть плоский список, отображающий данные, извлеченные из моей базы данных. Итак, все работает правильно. Но когда я проверяю один из отображаемых элементов, он проверяет их все. Я погуглил и попробовал несколько разных методов, которые я также использовал здесь. Либо ничего не проверяется, либо все проверяется в флажке. Не могли бы вы, ребята, взглянуть на мой код ниже и сообщить мне, если я чего-то не хватает?

Большое вам спасибо!!!

 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,
        }));
    }
}  

Ответ №1:

В настоящее время вы устанавливаете флажки в списке на checked={this.state.checked}

Не похоже, что вы используете метод onCheck и вместо этого обрабатываете событие в onPress . Поэтому, когда срабатывает ваш обработчик событий onPress, он переключает весь список, потому что каждый элемент в списке использует одно и то же состояние.

Вместо этого вам нужно отслеживать все элементы в проверенном состоянии массива. Вы захотите сделать что-то вроде:

 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
  />
)}
  

Комментарии:

1. извините за поздний ответ, у меня были сумасшедшие выходные, и теперь я просто возвращаюсь к этому. Я буду использовать это и посмотрю, работает ли это. Я обновлю вас через несколько минут.

2. Это дает мне ошибку типа: underfined не является объектом.

3. @Jca39A Вы обновили эту строку здесь? const currentItemIndex = items.findIndex(v => v.name === item.name) Я не знаю, какова ваша модель данных, поэтому вам нужно обновить эту строку, чтобы она соответствовала уникальному полю. В приведенном примере предполагается, что ваша модель данных выглядит примерно так: [{name: 'foo'}, {name: 'bar'}] тогда ` v.name === item.name ` это сработало бы. В противном случае он вернет undefined. Поэтому вам просто нужно обновить выражение, чтобы оно соответствовало уникальному полю в вашей модели данных.

4. все еще получаю то же сообщение об ошибке. моя модель данных — {[itemname: ‘cookies’]} . В нем говорится об этой строке ….элементы [currentItemIndex].проверено = !элементы [currentItemIndex] .checked…..is ошибка. У меня есть onPress именно так, как у вас есть выше. Но вот как я это изменил … я тоже думаю, что это неправильно. const currentItemIndex = items.findIndex(v => v.name === имя элемента.itemname)

5. Теперь я заставил его работать там, где он проверяет только по одному за раз. Я изменил свое проверенное состояние на this.state ={ checked: null,} а затем я изменил checked внутри флажка на ….checked={this.state.checked === item} . Итак, это работает, но это не позволит мне выбирать несколько элементов одновременно. Если я выберу один элемент, а затем попытаюсь выбрать другой. Он отменит выбор того, который я выбрал первым, а затем выберет новый элемент. Вы видели, как это происходило раньше?

Ответ №2:

Вот как я это решил, но теперь я не могу выбирать несколько элементов одновременно.

 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>
        )
    }