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