不变违规:试图获取超出范围索引NaN更改的平面列表状态

时间:2019-09-22 07:11:29

标签: reactjs react-native

我想向我的FlatList添加一个选择,这是我的代码。但是,当我长按项目并致电setCities时,我仍然可以记录更新后的城市,但显示出不变违反的错误。非常感谢您的帮助,谢谢!

const CityListScreen = ({ navigation }) => {
  const [cities, setCities] = useState([
    {
      name: 'Davao City',
      temp: 23,
      description: 'Cloudy',
      isSelected: false,
    },
    {
      name: 'Cebu City',
      temp: 26,
      description: 'Clear',
      isSelected: false,
    },
    {
      name: 'Tokyo City',
      temp: 23,
      description: 'Snow',
      isSelected: false,
    },
    {
      name: 'Singapore City',
      temp: 32,
      description: 'Sunny',
      isSelected: false,
    },
    {
      name: 'Dublin City',
      temp: 18,
      description: 'Snow',
      isSelected: false,
    }
  ]);

  const renderSeparator = () => {
    return (
      <View
        style={{
          height: 16,
          width: '100%',
          backgroundColor: 'transparent'
        }}
      />
    );
  }

  const onCitySelected = (city) => {
    city.isSelected = !city.isSelected;
    city.selectedClass = city.isSelected ?
      styles.itemContainerSelected : styles.itemContainer;

    const newCities = cities.map((item) => {
      return item.name === city.name ? 
        city : item;
    })

    console.log(newCities);

    setCities({ cities: newCities });
  }

  return (
    <View style={styles.container}>
      <FlatList
        data={cities}
        keyExtractor={item => item.name}
        renderItem={({ item }) => {
          return (
            <CityItem
              city={item}
              onLongPress={(city) => onCitySelected(city)}
            />
          );
        }}
        ItemSeparatorComponent={renderSeparator}
        contentContainerStyle={styles.flatList}
      />
    </View>
  );
};

编辑1 :(堆栈跟踪)

Invariant Violation: Invariant Violation: Tried to get frame for out of range index NaN

This error is located at:
    in VirtualizedList (at FlatList.js:632)
    in FlatList (at CityListScreen.js:84)
    in RCTView (at View.js:45)
    in View (at CityListScreen.js:70)
    in CityListScreen (at SceneView.js:9)
    in SceneView (at StackViewLayout.tsx:898)
    in RCTView (at View.js:45)
    in View (at StackViewLayout.tsx:897)
    in RCTView (at View.js:45)
    in View (at StackViewLayout.tsx:896)
    in RCTView (at View.js:45)
    in View (at createAnimatedComponent.js:151)
    in AnimatedComponent (at StackViewCard.tsx:106)
    in RCTView (at View.js:45)
    in View (at createAnimatedComponent.js:151)
    in AnimatedComponent (at screens.native.js:71)
    in Screen (at StackViewCard.tsx:93)
    in Card (at createPointerEventsContainer.tsx:95)
    in Container (at StackViewLayout.tsx:984)
    in RCTView (at View.js:45)
    in View (at screens.native.js:101)
    in ScreenContainer (at StackViewLayout.tsx:393)
    in RCTView (at View.js:45)
    in View (at createAnimatedComponent.js:151)
    in AnimatedComponent (at StackViewLayout.tsx:383)
    in PanGestureHandler (at StackViewLayout.tsx:376)
    in StackViewLayout (at withOrientation.js:30)
    in withOrientation (at StackView.tsx:104)
    in RCTView (at View.js:45)
    in View (at Transitioner.tsx:267)
    in Transitioner (at StackView.tsx:41)
    in StackView (at createNavigator.js:80)
    in Navigator (at createKeyboardAwareNavigator.js:12)
    in KeyboardAwareNavigator (at createAppContainer.js:430)
    in NavigationContainer (at App.js:55)
    in Provider (at App.js:54)
    in Provider (at App.js:53)
    in Provider (at App.js:52)
    in App (at withExpoRoot.js:20)
    in RootErrorBoundary (at withExpoRoot.js:19)
    in ExpoRootComponent (at renderApplication.js:35)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:98)
    in RCTView (at View.js:45)
    in View (at react-native-root-siblings/index.js:32)
    in RootSiblingsWrapper (at AppContainer.js:112)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:115)
    in AppContainer (at renderApplication.js:34)

This error is located at:
    in NavigationContainer (at App.js:55)
    in Provider (at App.js:54)
    in Provider (at App.js:53)
    in Provider (at App.js:52)
    in App (at withExpoRoot.js:20)
    in RootErrorBoundary (at withExpoRoot.js:19)
    in ExpoRootComponent (at renderApplication.js:35)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:98)
    in RCTView (at View.js:45)
    in View (at react-native-root-siblings/index.js:32)
    in RootSiblingsWrapper (at AppContainer.js:112)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:115)
    in AppContainer (at renderApplication.js:34)

编辑2:

setInterval()之后添加setCities()日志后的结果

state Array [
  Object {
    "description": "Cloudy",
    "isSelected": true,
    "name": "Davao City",
    "temp": 23,
  },
  Object {
    "description": "Clear",
    "isSelected": false,
    "name": "Cebu City",
    "temp": 26,
  },
  Object {
    "description": "Snow",
    "isSelected": false,
    "name": "Tokyo City",
    "temp": 23,
  },
  Object {
    "description": "Sunny",
    "isSelected": false,
    "name": "Singapore City",
    "temp": 32,
  },
  Object {
    "description": "Snow",
    "isSelected": false,
    "name": "Dublin City",
    "temp": 18,
  },
] object

1 个答案:

答案 0 :(得分:1)

哦,重新阅读您的代码后,我认为我已经解决了问题,请尝试并告诉我是否可行。 当传递给FlatList的数组不是数组时,通常会发生这种情况。您所在的城市州是一个对象。

在您的onCitySelected函数中-

 const onCitySelected = (city) => {
    city.isSelected = !city.isSelected;
    city.selectedClass = city.isSelected ?
      styles.itemContainerSelected : styles.itemContainer;

    const newCities = cities.map((item) => {
      return item.name === city.name ? 
        city : item;
    })

    console.log(newCities);

   // setCities({ cities: newCities });  change this //
      setCities(newCities);
  }