Javascript 我无法更改ListItem组件内开关的状态

Javascript 我无法更改ListItem组件内开关的状态,javascript,react-native,react-native-elements,Javascript,React Native,React Native Elements,我想做的是在这个组件中列出一个包含多个项的数组,这个数组包含每个单独项的布尔状态,如下所示 items : { "ISA InterChile" : [ { key : '7843', name : "ISA APP RRHH", fav: false }, { key : '7844', name : "Garantia y Obligaciones",

我想做的是在这个组件中列出一个包含多个项的数组,这个数组包含每个单独项的布尔状态,如下所示

  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.SeleccionClients是从下拉菜单中选择的,您可以从中选择项目,并在其中列出项目

编辑:这是整个视图和代码

    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),
            }}
          />
        )}
      />
    );
  }
}

等等,你没有使用UpdateItem.fav,顺便说一句,每当我点击一个状态时,我都会收到一个错误。我没有看到UpdateItem.fav的定义,你能分享一下你收到的错误吗?收到一个TypeError:更新不可替代实例的无效尝试this.props.data的值是多少?我在问题中向你展示的数组,项目数组
 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 });
    };