#javascript #reactjs #react-native #checkbox #expo
#javascript #reactjs #react-native #флажок #экспо
Вопрос:
Я хочу иметь возможность добавлять несколько флажков в мое собственное приложение expo react. Я предоставляю соответствующий код ниже. У меня есть массив в моем классе, который содержит подробную информацию о флажке, у него есть идентификатор, текст, который должен сопровождаться, и проверка того, установлен флажок или нет.
Мой код
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
inputTxt: "",
checks: [
{id: 1, txt: "first check", isChecked: false },
{id: 2, txt: "second check", isChecked: false }
]
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>Details Screen</Text>
<View>
<View style={styles.checkboxContainer}>
<CheckBox/>
{/* Add all the checkboxes from my this.state.checks array here */}
<Text style={styles.label}>Do you like React Native?</Text>
</View>
</View>
[...]
</View>
);
}
}
Ответ №1:
Вот как вы можете очень легко это реализовать.
Я использовал здесь функциональный компонент вместо компонента на основе классов, но базовая логика остается прежней:
Конечный результат:
Пример 1: Полный исходный код (с использованием функциональных компонентов и перехватов):
import React, { useState, useEffect } from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
CheckBox,
Button,
Modal,
} from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const data = [
{ id: 1, txt: 'first check', isChecked: false },
{ id: 2, txt: 'second check', isChecked: false },
{ id: 3, txt: 'third check', isChecked: false },
{ id: 4, txt: 'fourth check', isChecked: false },
{ id: 5, txt: 'fifth check', isChecked: false },
{ id: 6, txt: 'sixth check', isChecked: false },
{ id: 7, txt: 'seventh check', isChecked: false },
];
export default App = () => {
const [products, setProducts] = useState(data);
const handleChange = (id) => {
let temp = products.map((product) => {
if (id === product.id) {
return { ...product, isChecked: !product.isChecked };
}
return product;
});
setProducts(temp);
};
let selected = products.filter((product) => product.isChecked);
const renderFlatList = (renderData) => {
return (
<FlatList
data={renderData}
renderItem={({ item }) => (
<Card style={{ margin: 5 }}>
<View style={styles.card}>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
}}>
<CheckBox
value={item.isChecked}
onChange={() => {
handleChange(item.id);
}}
/>
<Text>{item.txt}</Text>
</View>
</View>
</Card>
)}
/>
);
};
return (
<View style={styles.container}>
<View style={{ flex: 1 }}>{renderFlatList(products)}</View>
<Text style={styles.text}>Selected </Text>
<View style={{ flex: 1 }}>{renderFlatList(selected)}</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
padding: 10,
margin: 5,
flexDirection: 'row',
justifyContent: 'space-between',
},
modalView: {
margin: 20,
backgroundColor: 'white',
borderRadius: 20,
padding: 5,
justifyContent: 'space-between',
alignItems: 'center',
elevation: 5,
},
text: {
textAlign: 'center',
fontWeight: 'bold',
},
});
Вы можете поиграть с готовым рабочим кодом здесь: Expo Snack
Пример 2: Полный исходный код (с использованием компонентов на основе классов):
import React, { useState, useEffect, Component } from 'react';
import {
Text,
View,
StyleSheet,
FlatList,
CheckBox,
Button,
Modal,
} from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const data = [
{ id: 1, txt: 'first check', isChecked: false },
{ id: 2, txt: 'second check', isChecked: false },
{ id: 3, txt: 'third check', isChecked: false },
{ id: 4, txt: 'fourth check', isChecked: false },
{ id: 5, txt: 'fifth check', isChecked: false },
{ id: 6, txt: 'sixth check', isChecked: false },
{ id: 7, txt: 'seventh check', isChecked: false },
];
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
products: data,
};
}
handleChange = (id) => {
let temp = this.state.products.map((product) => {
if (id === product.id) {
return { ...product, isChecked: !product.isChecked };
}
return product;
});
this.setState({
products: temp,
});
};
renderFlatList = (renderData) => {
return (
<FlatList
data={renderData}
renderItem={({ item }) => (
<Card style={{ margin: 5 }}>
<View style={styles.card}>
<View
style={{
flexDirection: 'row',
flex: 1,
justifyContent: 'space-between',
}}>
<CheckBox
value={item.isChecked}
onChange={() => {
this.handleChange(item.id);
}}
/>
<Text>{item.txt}</Text>
</View>
</View>
</Card>
)}
/>
);
};
render() {
let selected = this.state.products?.filter((product) => product.isChecked);
return (
<View style={styles.container}>
<View style={{ flex: 1 }}>
{this.renderFlatList(this.state.products)}
</View>
<Text style={styles.text}>Selected </Text>
<View style={{ flex: 1 }}>{this.renderFlatList(selected)}</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
card: {
padding: 10,
margin: 5,
flexDirection: 'row',
justifyContent: 'space-between',
},
modalView: {
margin: 20,
backgroundColor: 'white',
borderRadius: 20,
padding: 5,
justifyContent: 'space-between',
alignItems: 'center',
elevation: 5,
},
text: {
textAlign: 'center',
fontWeight: 'bold',
},
});
Вы можете поиграть с готовым рабочим кодом здесь: Expo Snack
Комментарии:
1. Спасибо, я не видел такого подробного ответа на этот вопрос ранее.
2. Рад, что это помогло, счастливого кодирования :)
3. Не могли бы вы обновить свой ответ, чтобы показать решение и для использования с классами, потому что использование крючков useSate в классах немного сложно, и будущие пользователи могут захотеть это увидеть.