我尝试使用从json获取的名称创建动态复选框,this issue看起来与我需要的相同,但如果没有代码解释,我无法实现我的目标,
我有一个像这样的json示例:
this.state = {
data : [
{
"name": "ALL",
},
{
"name": "Android",
},
{
"name": "iOS",
},
{
"name": "React Native",
}
]}
并使用以下代码:
<CheckBox
center
title={this.state.data[1].name}
onPress={() => {this.setState({checked: !this.state.checked})}}
checked={this.state.checked}
/>
复选框运行良好,但它只显示了json的第二个值
我的目标是将所有json值显示在flatlist中并使复选框运行良好,
现在我可以将这些json显示到FlatList中,但复选框不起作用
import React, { Component } from 'react';
import {
Text, View, StyleSheet, Alert, FlatList
} from 'react-native';
import Dimensions from 'Dimensions';
import { CheckBox } from 'react-native-elements'
const DeviceWidth = Dimensions.get('window').width;
const DeviceHeight = Dimensions.get('window').height;
class MedicalClearlance extends React.Component {
constructor(props){
super(props);
this.state = {
checked:[],
data : [
{
"name": "ALL",
},
{
"name": "Android",
},
{
"name": "iOS",
},
{
"name": "React Native",
}
]}
}
render() {
return (
<FlatList
data={ this.state.data }
renderItem={({item, index}) =>
<CheckBox
center
title={item.name}
onPress={() => {this.setState({checked: !this.state.checked}), console.log(this.state.checked +' '+ index)}}
checked={this.state.checked}/>
}
/>
);
}
}
任何人都可以帮助我如何实现我的目标?
答案 0 :(得分:4)
Ahsan Ali提供的答案将起作用。 但是它缺少非常重要的代码行。
<FlatList/>
组件中添加此extraData
={this.state}
。每当状态改变时,这将允许FlatList组件重新呈现。渲染方法将如下所示:
handleChange = (index) => {
let checked = [...this.state.checked];
checked[index] = !checked[index];
this.setState({ checked });
}
render() {
let { data, checked } = this.state;
return (
<FlatList
data={data}
extraData={this.state}
renderItem={({ item, index }) =>
<CheckBox
center
title={item.name}
onPress={() => this.handleChange(index)}
checked={checked[index]} />
}
/>
);
}
通过将extraData = {this.state}传递给FlatList,我们可以确保FlatList 当state.selected改变时,它本身将重新渲染。没有设定 这个道具,FlatList不知道它需要重新渲染任何物品 因为它也是一个PureComponent并且prop比较不会 显示任何更改。
更多信息可以在React-Native Flat-List文档here中找到。
如果您使用的是Ahsun Ali's帖子中的代码,则可能会遇到另一个错误。
componentWillMount()
方法
不推荐使用。在这种情况下,请务必使用componentDidMount()
代替。希望这对人们有帮助!
答案 1 :(得分:2)
你需要填充checked
数组,以便在之后操作它。
constructor() {
super();
this.state = {
data: [
{
"name": "ALL",
},
{
"name": "Android",
},
{
"name": "iOS",
},
{
"name": "React Native",
}
],
checked: []
}
}
componentWillMount() {
let { data, checked } = this.state;
let intialCheck = data.map(x => false);
this.setState({ checked: intialCheck })
}
并传递所选复选框的index
以进行更新
handleChange = (index) => {
let checked = [...this.state.checked];
checked[index] = !checked[index];
this.setState({ checked });
}
render() {
let { data, checked } = this.state;
return (
<FlatList
data={data}
renderItem={({ item, index }) =>
<CheckBox
center
title={item.name}
onPress={() => this.handleChange(index)}
checked={checked[index]} />
}
/>
);
}
我希望它有所帮助!
答案 2 :(得分:0)
您可以尝试进行多次选择,请参考链接-> https://facebook.github.io/react-native/docs/flatlist
class MyListItem extends React.PureComponent
{
_onPress = () => {
this.props.onPressItem(this.props.id);
};
render() {
const textColor = this.props.selected ? 'red' : 'black';
return (
<TouchableOpacity onPress={this._onPress}>
<View>
<Text style={{color: textColor}}>{this.props.title}</Text>
</View>
</TouchableOpacity>
);
}
}
class MultiSelectList extends React.PureComponent {
state = {selected: (new Map(): Map<string, boolean>)};
_keyExtractor = (item, index) => item.id;
_onPressItem = (id: string) => {
// updater functions are preferred for transactional updates
this.setState((state) => {
// copy the map rather than modifying state.
const selected = new Map(state.selected);
selected.set(id, !selected.get(id)); // toggle
return {selected};
});
};
_renderItem = ({item}) => (
<MyListItem
id={item.id}
onPressItem={this._onPressItem}
selected={!!this.state.selected.get(item.id)}
title={item.title}
/>
);
render() {
return (
<FlatList
data={this.props.data}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
);
}
}
for(const ele of this.state.selected.keys())
console.log(ele);
//**after that you could get all the selected keys or values from something like this**