如果一个项目在 React Native 中的状态数组中,在复选框中显示复选框的正确方法是什么?



当前我正在尝试在三元运算符中使用状态检查,该运算符检查元素是否在状态数组中。如果是,请选中复选框。如果没有取消选中该框。我目前正在使用类似的东西

import React from "react";
import { ScrollView, ActivityIndicator, StyleSheet, Image, ImageBackground, View, Text, TextInput, TouchableHighlight, TouchableOpacity, Modal, Alert, Animated, Dimensions, PanResponder, FlatList } from "react-native";
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.state = {
showFilter: false,
phraseFilters: [5,4,3,2,1],
};
}
showFilter() {
this.setState({showFilter: true})
}
closeFilter()  {
this.setState({showFilter: false})
}
render() {
return (
<View>
<Modal
animationType="fade"
transparent
visible={this.state.showFilter}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.overlay}>
</View>
</Modal>
<Modal
animationType="slide"
transparent
visible={this.state.showFilter}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.filterView}>
<View style={styles.filterModal}>
<TouchableOpacity
onPress={() => {
this.closeFilter();
}}>
<View style={styles.closeModal}>
<View style={styles.closeModalButton}></View>
</View>
</TouchableOpacity>
<View style={styles.filterData}>
<View style={styles.filterTitle}>
<Text>Mastery Levels</Text>
</View>
<View style={styles.filterDescription}>
<Text><Text style={styles.filterText}>Mastery levels separate phrases by exceeds, meets, and marginal</Text></Text>
</View>
<View style={styles.filterItem}>
<View style={styles.filterItemTextArea}>
<Text style={styles.filterText}>Exceptional</Text>
</View>
<TouchableOpacity
onPress={() => {
if (this.state.phraseFilters.includes(5)) {
this.state.phraseFilters.splice(this.state.phraseFilters.indexOf(5), 1)
console.log(this.state.phraseFilters)
} else {
this.state.phraseFilters.push(5)
console.log(this.state.phraseFilters)
console.log(this.state.phraseFilters.includes(5))
}
}}>
<View style={styles.filterCheckboxArea}>
{this.state.phraseFilters.includes(5) ?
(<Image source={require('./assets/images/checked.png')}
style={styles.filterCheckbox}/>) :
(<Image source={require('./assets/images/unchecked.png')}
style={styles.filterCheckbox}/>)
}
</View>
</TouchableOpacity>
</View>
<View style={styles.filterItem}>
<View style={styles.filterItemTextArea}>
<Text style={styles.filterText}>Excellent</Text>
</View>
<TouchableOpacity
onPress={() => {
if (this.state.phraseFilters.includes(4)) {
this.state.phraseFilters.splice(this.state.phraseFilters.indexOf(4), 1)
} else {
this.state.phraseFilters.push(4)
console.log(this.state.phraseFilters)
console.log(this.state.phraseFilters.includes(4))
}
}}>
<View style={styles.filterCheckboxArea}>
{this.state.phraseFilters.includes(4) ?
(<Image source={require('./assets/images/checked.png')}
style={styles.filterCheckbox}/>) :
(<Image source={require('./assets/images/unchecked.png')}
style={styles.filterCheckbox}/>)
}
</View>
</TouchableOpacity>
</View>
<View style={styles.filterItem}>
<View style={styles.filterItemTextArea}>
<Text style={styles.filterText}>Competent</Text>
</View>
<TouchableOpacity
onPress={() => {
if (this.state.phraseFilters.includes(3)) {
this.state.phraseFilters.splice(this.state.phraseFilters.indexOf(5), 1)
} else {
this.state.phraseFilters.push(3)
console.log(this.state.phraseFilters)
console.log(this.state.phraseFilters.includes(3))
}
}}>
<View style={styles.filterCheckboxArea}>
{this.state.phraseFilters.includes(3) ?
(<Image source={require('./assets/images/checked.png')}
style={styles.filterCheckbox}/>) :
(<Image source={require('./assets/images/unchecked.png')}
style={styles.filterCheckbox}/>)
}
</View>
</TouchableOpacity>
</View>
<View style={styles.filterItem}>
<View style={styles.filterItemTextArea}>
<Text style={styles.filterText}>Marginal</Text>
</View>
<TouchableOpacity
onPress={() => {
if (this.state.phraseFilters.includes(2)) {
this.state.phraseFilters.splice(this.state.phraseFilters.indexOf(2), 1)
} else {
this.state.phraseFilters.push(2)
console.log(this.state.phraseFilters)
console.log(this.state.phraseFilters.includes(2))
}
}}>
<View style={styles.filterCheckboxArea}>
{this.state.phraseFilters.includes(2) ?
(<Image source={require('./assets/images/checked.png')}
style={styles.filterCheckbox}/>) :
(<Image source={require('./assets/images/unchecked.png')}
style={styles.filterCheckbox}/>)
}
</View>
</TouchableOpacity>
</View>
<View style={styles.filterItem}>
<View style={styles.filterItemTextArea}>
<Text style={styles.filterText}>Unsatisfactory</Text>
</View>
<TouchableOpacity
onPress={() => {
if (this.state.phraseFilters.includes(1)) {
this.state.phraseFilters.splice(this.state.phraseFilters.indexOf(1), 1)
} else {
this.state.phraseFilters.push(1)
console.log(this.state.phraseFilters)
console.log(this.state.phraseFilters.includes(1))
}
}}>
<View style={styles.filterCheckboxArea}>
{this.state.phraseFilters.includes(1) ?
(<Image source={require('./assets/images/checked.png')}
style={styles.filterCheckbox}/>) :
(<Image source={require('./assets/images/unchecked.png')}
style={styles.filterCheckbox}/>)
}
</View>
</TouchableOpacity>
</View>
</View>
</View>
</View>
</Modal>
<View style={styles.container}>
<View style={styles.leftMargin}>
<TouchableOpacity
onPress={() => {
this.showFilter();
}}>
<Image source={require('./assets/images/filter.png')} style={styles.filter}></Image>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
backgroundColor: "white",
width: '375px',
height: '60px',
flexDirection: 'row'
// top: '50px',
},
leftMargin: {
height: '60px',
width: '60px',
justifyContent: 'center',
alignItems: 'center'
},
searchBar: {
height: '60px',
width: '255px',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},
searchButton: {
height: '60px',
width: '60px',
justifyContent: 'center',
alignItems: 'center'
},
filter: {
height: '24px',
width: '24px'
},
search: {
height: '24px',
width: '24px'
},
searchInput: {
height: '38px',
width: '255px',
borderWidth: '1px',
borderColor: '#979797'
},
filterView: {
width: '100%',
//   borderWidth: 1,
alignItems: 'center',
justifyContent: 'center',
//   backgroundColor: 'white',
flex:1,
justifyContent: 'flex-end',
alignItems: 'center'
//   flex: 1
},
overlay: {
backgroundColor: 'rgba(0,0,0,0.1523)',
flex:1,
justifyContent: 'flex-end',
alignItems: 'center'
},
filterModal: {
width: '375px',
backgroundColor: 'white',
marginBottom: 164,
flexDirection: 'column'
},
closeModal: {
width: '100%',
height: '20px',
alignItems: 'center',
justifyContent: 'center'
},
closeModalButton: {
width: 30,
height: 4,
backgroundColor: '#979797',
borderRadius: 2
},
filterData: {
marginLeft: 28,
marginRight: 28,
flexDirection: 'column',
marginBottom: 15
},
filterTitle: {
height: 32,
marginBottom: 6
},
filterDescription: {
paddingBottom: 13
},
filterText: {
fontSize: 16,
},
filterItem: {
height: 48,
flexDirection: 'row',
alignItems: 'center'
},
filterItemTextArea: {
flex: 1
},
filterCheckboxArea: {
width:30,
alignItems:'center',
justifyContent:'center'
},
filterCheckbox: {
width:24,
height:24
}

});
export default SearchBar;

但它不能正确地添加复选框和从复选框中删除复选框。正确的方法是什么?

如果有任何不同的话,状态检查是以模态进行的。项目回购可在此处查看https://github.com/nimbusdin/stackreactnative

问题

您正在更改状态对象。array.prptype.splice执行一个在位数组突变。CCD_ 1也使阵列发生突变。

正确使用状态

不直接修改状态例如,这不会重新渲染组件:

// Wrong
this.state.comment = 'Hello';
Instead, use setState():
// Correct
this.setState({comment: 'Hello'});
onPress={() => {
if (this.state.phraseFilters.includes(4)) {
this.state.phraseFilters.splice( // <-- state mutation!!
this.state.phraseFilters.indexOf(4),
1
);
} else {
this.state.phraseFilters.push(4); // <-- state mutation!!
}
}}>

解决方案

正确更新状态。任何时候你需要更新状态,你都应该先复制它,然后更新副本。

搜索索引,如果找到,则按索引过滤当前phaseFilters状态,否则,浅层复制以前的状态并附加相位过滤器值。

onPress={() => {
const index = this.state.phraseFilters.indexOf(5);
if (index !== -1) {
this.setState((prevState) => ({
phraseFilters: prevState.phraseFilters.filter(
(_, i) => i !== index
),
}));
} else {
this.setState((prevState) => ({
phraseFilters: [...prevState.phraseFilters, 5],
}));
}
}}>

最新更新