我无法更改 ListItem 组件内开关的状态
I'm unable to change states on switches inside ListItem component
我想做的是在这个组件中列出一个包含多个项目的数组,这个数组包含每个单独项目的布尔状态,就像这样。
items : {
"ISA InterChile" : [
{
key : '7843',
name : "ISA APP RRHH",
fav: false
},
{
key : '7844',
name : "Garantia y Obligaciones",
fav: false
},
{
key : '7855',
name : "Que se yo",
fav: true
},
{
key : '7899',
name : "Random",
fav: true
}
],
"DSAC Chile" : [
{
key : '5022',
name: 'ADAM RRHH',
fav: true
},
{
key : '5023',
name: 'Name of Project 4',
fav: false
}
],
"Banco BCI" : [
{
key : '1101',
name: 'Name of Project 3',
fav: false
},
{
key : '1014',
name: 'Name of Project 4',
fav: false
},
{
key : '1170',
name: 'Name of Project 5',
fav: false
},
{
key : '1033',
name: 'Name of Project 6',
fav: false
},
{
key : '1101',
name: 'Name of Project 7',
fav: false
},
{
key : '1014',
name: 'Name of Project 8',
fav: false
},
{
key : '1170',
name: 'Name of Project 9',
fav: false
},
{
key : '1033',
name: 'Name of Project 10',
fav: false
}
]
},
但是每当我尝试改变状态时,它会立即变回之前的状态,这就是代码。
{
this.state.items[this.state.SeleccionClientes].map(value => (
<ListItem
containerStyle={{backgroundColor: '#ffffff', width: widthPercentageToDP('87.1%'), height: 64, alignItems: 'center', justifyContent: 'center', alignSelf: 'center', marginTop: heightPercentageToDP('2.8%'), paddingHorizontal: 0}}
topDivider={false}
bottomDivider={true}
titleStyle={{
marginLeft: 0,
fontSize: 16,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 24,
letterSpacing: 0.15,
textAlign: "left",
color: "#707070"
}}
subtitleStyle={{
marginLeft: 0,
fontSize: 14,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 20,
letterSpacing: 0.25,
textAlign: "left",
color: "#c4c4c4"
}}
title={`${value.name}`}
subtitle={`ID ${value.key}`}
switch={{
value: value.fav, onValueChange: () => !value.fav
}}
/>
))
}
this.state.SeleccionClientes 来自下拉菜单,您可以从下拉菜单中 select items 中的项目,然后列出里面的项目
编辑:这是整个视图和代码
import * as React from 'react';
import {View, Text, Image, StatusBar, SafeAreaView, TouchableOpacity, ScrollView, RefreshControl, FlatList} from 'react-native';
import { Header, ListItem } from 'react-native-elements';
import ModalDropdown from 'react-native-modal-dropdown';
import Images from '../../Assets/values/images';
import {
RFPercentage as rfp,
RFValue as rfv,
} from 'react-native-responsive-fontsize';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
heightPercentageToDP,
widthPercentageToDP,
} from 'react-native-responsive-screen';
import styles from '../../Assets/values/styles/HoursReport/ClientsProyects/ClientsProyectsStyle';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import DataManager from '../../../Util/CrossUtils/DataManager';
export default class ClientsProyectsScreen extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
items : {
"ISA InterChile" : [
{
key : '7843',
name : "ISA APP RRHH",
fav: false
},
{
key : '7844',
name : "Garantia y Obligaciones",
fav: false
},
{
key : '7855',
name : "Que se yo",
fav: true
},
{
key : '7899',
name : "Random",
fav: true
}
],
"DSAC Chile" : [
{
key : '5022',
name: 'ADAM RRHH',
fav: true
},
{
key : '5023',
name: 'Name of Project 4',
fav: false
}
],
"Banco BCI" : [
{
key : '1101',
name: 'Name of Project 3',
fav: false
},
{
key : '1014',
name: 'Name of Project 4',
fav: true
},
{
key : '1170',
name: 'Name of Project 5',
fav: false
},
{
key : '1033',
name: 'Name of Project 6',
fav: false
},
{
key : '1102',
name: 'Name of Project 7',
fav: true
},
{
key : '1114',
name: 'Name of Project 8',
fav: false
},
{
key : '1175',
name: 'Name of Project 9',
fav: false
},
{
key : '1303',
name: 'Name of Project 10',
fav: false
}
]
},
SeleccionClientes: '',
}
}
updateFav = item => {
const newData = this.state.items[this.state.SeleccionClientes];
const uodatedItem = newData.find(x => x.key === item.key);
uodatedItem.fav = !item.fav;
this.setState({ data: newData });
//You can also have a callback from parent component to update parent state
};
render() {
return (
<>
<StatusBar translucent backgroundColor="transparent" />
<SafeAreaView style={{backgroundColor: '#fafafa'}}/>
{/*
<Header
backgroundImage={Images.header_nav}
backgroundImageStyle={styles.HeaderImagenCP}
leftComponent={
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<View><Image style={styles.HeaderHorizontal} source={Images.back}/></View>
</TouchableOpacity>
}
centerComponent={{text: 'Imputar horas', ellipsizeMode: 'clip', style: styles.HeaderHoursReportCP }}
placement='center'
/>
*/}
<View style={styles.ContainerBackground}>
<View style={{flexDirection: 'row'}}>
<View style={{alignItems: 'flex-start', justifyContent: 'flex-start', alignSelf: 'flex-start', marginTop: heightPercentageToDP('2.2%'), marginLeft: widthPercentageToDP('6.3%')}}>
<Text style={{
fontSize: 18,
fontWeight: "500",
fontStyle: "normal",
lineHeight: 35,
letterSpacing: 0,
textAlign: "left",
color: "#707070"
}}>Proyectos</Text>
</View>
<TouchableOpacity style={{position: 'absolute', alignItems: 'flex-end', justifyContent: 'flex-end', alignSelf: 'flex-end', paddingBottom: heightPercentageToDP('0.5%'), left: widthPercentageToDP('90%')}} onPress={() => this.props.navigation.goBack()}>
<Image source={Images.close_modal}/>
</TouchableOpacity>
</View>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="handled"
enableOnAndroid={true}>
{/*
<View style={{alignItems: 'flex-end', justifyContent: 'flex-end', alignSelf: 'flex-end', marginRight: widthPercentageToDP('6.3%')}}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Image source={Images.close_modal}/>
</TouchableOpacity>
</View>
*/}
<View style={styles.Left}>
<Text style={styles.TituloInputOnBlur}>Cliente</Text>
</View>
<View style={styles.Center}>
<ModalDropdown
dropdownTextStyle={styles.dropdownTextStyle}
dropdownTextHighlightStyle={styles.dropdownTextHighlightStyle}
defaultValue={'Seleccionar'}
style={styles.dropStyle}
textStyle={{
padding: 0,
margin: 0,
fontSize: rfv(16),
paddingVertical: hp('1.2%'),
fontWeight: 'normal',
fontStyle: 'normal',
textAlign: 'left',
//color: Motivo != 'Seleccionar' ? '#1a1a1a' : '#c4c4c4',
}}
onSelect={(index, value) => this.setState({SeleccionClientes: value})}
options={Object.keys(this.state.items)}
/>
</View>
<View>
{
this.state.SeleccionClientes !== '' ?
<View>
{
<FlatList
data={this.state.items[this.state.SeleccionClientes]}
renderItem={({item, index}) => (
<ListItem
containerStyle={{backgroundColor: '#fafafa', width: widthPercentageToDP('87.1%'), height: 64, alignItems: 'center', justifyContent: 'center', alignSelf: 'center', marginTop: heightPercentageToDP('2.8%'), paddingHorizontal: 0}}
topDivider={false}
bottomDivider={true}
titleStyle={{
marginLeft: 0,
fontSize: 16,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 24,
letterSpacing: 0.15,
textAlign: "left",
color: "#707070"
}}
subtitleStyle={{
marginLeft: 0,
fontSize: 14,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 20,
letterSpacing: 0.25,
textAlign: "left",
color: "#c4c4c4"
}}
title={`${item.name}`}
subtitle={`ID ${item.key}`}
switch={{
//trackColor: {false: "#767577", true: "#81b0ff"},
//thumbColor: item.fav ? "#1062cc" : "#f4f3f4",
value: item.fav[index],
onValueChange: () => {this.updateFav(item)}
}}
/>
)}
/>
}
</View>
:
<View style={{alignItems: 'center', justifyContent: 'center', alignSelf: 'center'}}>
<View style={{marginTop: heightPercentageToDP('11%')}}>
<Image style={{marginBottom: heightPercentageToDP('2.8%')}} source={Images.sad_face}/>
</View>
<Text style={{
fontSize: 18,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 35,
letterSpacing: 0,
textAlign: "left",
color: "#c4c4c4"
}}>Sin proyectos activos</Text>
</View>
}
</View>
<View style={styles.BottomPush} />
</KeyboardAwareScrollView>
</View>
</>
);
}
}
您没有更新状态,您的开关从状态对象中获取值。最好使用平面列表而不是地图,因为它在性能方面有好处。这将是您可以采用的示例方法。
class CustomFlatList extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data,
};
}
updateFav = item => {
const newData = [...this.state.data];
const uodatedItem = newData.find(x => x.key === item.key);
uodatedItem.fav = !item.fav;
this.setState({ data: newData });
//You can also have a callback from parent component to update parent state
};
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
title={`${item.name}`}
subtitle={`ID ${item.key}`}
switch={{
value: item.fav,
onValueChange: () => this.updateFav(item),
}}
/>
)}
/>
);
}
}
--完整代码后更新代码
您必须更新 updateFav 函数,如下所示。
updateFav = item => {
const newData = [...this.state.items[this.state.SeleccionClientes]];
const updateItem = newData.find(x => x.key === item.key);
updateItem.fav = !item.fav;
const updatedArray = Object.assign(this.state.items);
updatedArray[this.state.SeleccionClientes] = newData;
this.setState({ items: updatedArray });
};
我想做的是在这个组件中列出一个包含多个项目的数组,这个数组包含每个单独项目的布尔状态,就像这样。
items : {
"ISA InterChile" : [
{
key : '7843',
name : "ISA APP RRHH",
fav: false
},
{
key : '7844',
name : "Garantia y Obligaciones",
fav: false
},
{
key : '7855',
name : "Que se yo",
fav: true
},
{
key : '7899',
name : "Random",
fav: true
}
],
"DSAC Chile" : [
{
key : '5022',
name: 'ADAM RRHH',
fav: true
},
{
key : '5023',
name: 'Name of Project 4',
fav: false
}
],
"Banco BCI" : [
{
key : '1101',
name: 'Name of Project 3',
fav: false
},
{
key : '1014',
name: 'Name of Project 4',
fav: false
},
{
key : '1170',
name: 'Name of Project 5',
fav: false
},
{
key : '1033',
name: 'Name of Project 6',
fav: false
},
{
key : '1101',
name: 'Name of Project 7',
fav: false
},
{
key : '1014',
name: 'Name of Project 8',
fav: false
},
{
key : '1170',
name: 'Name of Project 9',
fav: false
},
{
key : '1033',
name: 'Name of Project 10',
fav: false
}
]
},
但是每当我尝试改变状态时,它会立即变回之前的状态,这就是代码。
{
this.state.items[this.state.SeleccionClientes].map(value => (
<ListItem
containerStyle={{backgroundColor: '#ffffff', width: widthPercentageToDP('87.1%'), height: 64, alignItems: 'center', justifyContent: 'center', alignSelf: 'center', marginTop: heightPercentageToDP('2.8%'), paddingHorizontal: 0}}
topDivider={false}
bottomDivider={true}
titleStyle={{
marginLeft: 0,
fontSize: 16,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 24,
letterSpacing: 0.15,
textAlign: "left",
color: "#707070"
}}
subtitleStyle={{
marginLeft: 0,
fontSize: 14,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 20,
letterSpacing: 0.25,
textAlign: "left",
color: "#c4c4c4"
}}
title={`${value.name}`}
subtitle={`ID ${value.key}`}
switch={{
value: value.fav, onValueChange: () => !value.fav
}}
/>
))
}
this.state.SeleccionClientes 来自下拉菜单,您可以从下拉菜单中 select items 中的项目,然后列出里面的项目
编辑:这是整个视图和代码
import * as React from 'react';
import {View, Text, Image, StatusBar, SafeAreaView, TouchableOpacity, ScrollView, RefreshControl, FlatList} from 'react-native';
import { Header, ListItem } from 'react-native-elements';
import ModalDropdown from 'react-native-modal-dropdown';
import Images from '../../Assets/values/images';
import {
RFPercentage as rfp,
RFValue as rfv,
} from 'react-native-responsive-fontsize';
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
heightPercentageToDP,
widthPercentageToDP,
} from 'react-native-responsive-screen';
import styles from '../../Assets/values/styles/HoursReport/ClientsProyects/ClientsProyectsStyle';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import DataManager from '../../../Util/CrossUtils/DataManager';
export default class ClientsProyectsScreen extends React.Component<any, any> {
constructor(props: any) {
super(props);
this.state = {
items : {
"ISA InterChile" : [
{
key : '7843',
name : "ISA APP RRHH",
fav: false
},
{
key : '7844',
name : "Garantia y Obligaciones",
fav: false
},
{
key : '7855',
name : "Que se yo",
fav: true
},
{
key : '7899',
name : "Random",
fav: true
}
],
"DSAC Chile" : [
{
key : '5022',
name: 'ADAM RRHH',
fav: true
},
{
key : '5023',
name: 'Name of Project 4',
fav: false
}
],
"Banco BCI" : [
{
key : '1101',
name: 'Name of Project 3',
fav: false
},
{
key : '1014',
name: 'Name of Project 4',
fav: true
},
{
key : '1170',
name: 'Name of Project 5',
fav: false
},
{
key : '1033',
name: 'Name of Project 6',
fav: false
},
{
key : '1102',
name: 'Name of Project 7',
fav: true
},
{
key : '1114',
name: 'Name of Project 8',
fav: false
},
{
key : '1175',
name: 'Name of Project 9',
fav: false
},
{
key : '1303',
name: 'Name of Project 10',
fav: false
}
]
},
SeleccionClientes: '',
}
}
updateFav = item => {
const newData = this.state.items[this.state.SeleccionClientes];
const uodatedItem = newData.find(x => x.key === item.key);
uodatedItem.fav = !item.fav;
this.setState({ data: newData });
//You can also have a callback from parent component to update parent state
};
render() {
return (
<>
<StatusBar translucent backgroundColor="transparent" />
<SafeAreaView style={{backgroundColor: '#fafafa'}}/>
{/*
<Header
backgroundImage={Images.header_nav}
backgroundImageStyle={styles.HeaderImagenCP}
leftComponent={
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<View><Image style={styles.HeaderHorizontal} source={Images.back}/></View>
</TouchableOpacity>
}
centerComponent={{text: 'Imputar horas', ellipsizeMode: 'clip', style: styles.HeaderHoursReportCP }}
placement='center'
/>
*/}
<View style={styles.ContainerBackground}>
<View style={{flexDirection: 'row'}}>
<View style={{alignItems: 'flex-start', justifyContent: 'flex-start', alignSelf: 'flex-start', marginTop: heightPercentageToDP('2.2%'), marginLeft: widthPercentageToDP('6.3%')}}>
<Text style={{
fontSize: 18,
fontWeight: "500",
fontStyle: "normal",
lineHeight: 35,
letterSpacing: 0,
textAlign: "left",
color: "#707070"
}}>Proyectos</Text>
</View>
<TouchableOpacity style={{position: 'absolute', alignItems: 'flex-end', justifyContent: 'flex-end', alignSelf: 'flex-end', paddingBottom: heightPercentageToDP('0.5%'), left: widthPercentageToDP('90%')}} onPress={() => this.props.navigation.goBack()}>
<Image source={Images.close_modal}/>
</TouchableOpacity>
</View>
<KeyboardAwareScrollView
keyboardShouldPersistTaps="handled"
enableOnAndroid={true}>
{/*
<View style={{alignItems: 'flex-end', justifyContent: 'flex-end', alignSelf: 'flex-end', marginRight: widthPercentageToDP('6.3%')}}>
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Image source={Images.close_modal}/>
</TouchableOpacity>
</View>
*/}
<View style={styles.Left}>
<Text style={styles.TituloInputOnBlur}>Cliente</Text>
</View>
<View style={styles.Center}>
<ModalDropdown
dropdownTextStyle={styles.dropdownTextStyle}
dropdownTextHighlightStyle={styles.dropdownTextHighlightStyle}
defaultValue={'Seleccionar'}
style={styles.dropStyle}
textStyle={{
padding: 0,
margin: 0,
fontSize: rfv(16),
paddingVertical: hp('1.2%'),
fontWeight: 'normal',
fontStyle: 'normal',
textAlign: 'left',
//color: Motivo != 'Seleccionar' ? '#1a1a1a' : '#c4c4c4',
}}
onSelect={(index, value) => this.setState({SeleccionClientes: value})}
options={Object.keys(this.state.items)}
/>
</View>
<View>
{
this.state.SeleccionClientes !== '' ?
<View>
{
<FlatList
data={this.state.items[this.state.SeleccionClientes]}
renderItem={({item, index}) => (
<ListItem
containerStyle={{backgroundColor: '#fafafa', width: widthPercentageToDP('87.1%'), height: 64, alignItems: 'center', justifyContent: 'center', alignSelf: 'center', marginTop: heightPercentageToDP('2.8%'), paddingHorizontal: 0}}
topDivider={false}
bottomDivider={true}
titleStyle={{
marginLeft: 0,
fontSize: 16,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 24,
letterSpacing: 0.15,
textAlign: "left",
color: "#707070"
}}
subtitleStyle={{
marginLeft: 0,
fontSize: 14,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 20,
letterSpacing: 0.25,
textAlign: "left",
color: "#c4c4c4"
}}
title={`${item.name}`}
subtitle={`ID ${item.key}`}
switch={{
//trackColor: {false: "#767577", true: "#81b0ff"},
//thumbColor: item.fav ? "#1062cc" : "#f4f3f4",
value: item.fav[index],
onValueChange: () => {this.updateFav(item)}
}}
/>
)}
/>
}
</View>
:
<View style={{alignItems: 'center', justifyContent: 'center', alignSelf: 'center'}}>
<View style={{marginTop: heightPercentageToDP('11%')}}>
<Image style={{marginBottom: heightPercentageToDP('2.8%')}} source={Images.sad_face}/>
</View>
<Text style={{
fontSize: 18,
fontWeight: "normal",
fontStyle: "normal",
lineHeight: 35,
letterSpacing: 0,
textAlign: "left",
color: "#c4c4c4"
}}>Sin proyectos activos</Text>
</View>
}
</View>
<View style={styles.BottomPush} />
</KeyboardAwareScrollView>
</View>
</>
);
}
}
您没有更新状态,您的开关从状态对象中获取值。最好使用平面列表而不是地图,因为它在性能方面有好处。这将是您可以采用的示例方法。
class CustomFlatList extends Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data,
};
}
updateFav = item => {
const newData = [...this.state.data];
const uodatedItem = newData.find(x => x.key === item.key);
uodatedItem.fav = !item.fav;
this.setState({ data: newData });
//You can also have a callback from parent component to update parent state
};
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
title={`${item.name}`}
subtitle={`ID ${item.key}`}
switch={{
value: item.fav,
onValueChange: () => this.updateFav(item),
}}
/>
)}
/>
);
}
}
--完整代码后更新代码
您必须更新 updateFav 函数,如下所示。
updateFav = item => {
const newData = [...this.state.items[this.state.SeleccionClientes]];
const updateItem = newData.find(x => x.key === item.key);
updateItem.fav = !item.fav;
const updatedArray = Object.assign(this.state.items);
updatedArray[this.state.SeleccionClientes] = newData;
this.setState({ items: updatedArray });
};