当数据属性更改为空数组时,本机 FlatList 不会重新呈现

React native FlatList not rerendering when data prop changes to empty array

我有一个 FlatList 和一个从 Redux

拉取的 data 道具
  render() {
    return (
      <View>
        <FlatList
          data={this.props.arrayOfPlacesFromRedux}
          renderItem={({item}) => {.......

每当我发送对 arrayOfPlacesFromRedux 的更改(即添加或删除子项)时,FlatList 重新呈现....UNLESS 我从中删除所有子项数组(即使长度为零)。
arrayOfPlacesFromRedux 从正长度变为零长度时,FlatList 不会重新呈现......但是所有其他类型的更改数组确实会导致 FlatList 重新渲染

更新 02/27 下面是我用来更新 Redux 的 reducer arrayOfPlacesFromRedux

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case UPDATE_PLACES_ARRAY:
      return {...state, arrayOfPlaces: action.payload};
    default:
      return state;
  }
};

在上面提到的 FlatList 不重新渲染的情况下.....action.payload 是一个空数组

可能需要用到ListEmptyComponent,这是FlatList自带的prop,src.

老实说,我不确定为什么当你更新你的状态时它没有 re-render,或者为什么他们添加了一个特定的 function/prop 来在数组为空时呈现,但是从文档说明这是需要的。

你可以这样做:

  <SafeAreaView style={styles.container}>
      <FlatList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={(item) => item.id}
        extraData={selectedId}
-->     ListEmptyComponent={() => <MyComponent />}
      />
    </SafeAreaView>

问题缺少一些重要的代码。 React 和 Redux 需要改变数组引用,这意味着组件在状态改变时重新渲染,数组引用需要改变。

https://snack.expo.dev/RrFFxfeWY

现场演示

这里是最有趣的部分:

如果您有如下基本组件:


const MyList = () => {
  const [data, setData] = React.useState([
    '#FF0000',
    '#FF8000',
    '#FFFF00',
  ]);

  return (
    <>
      <Text>List poping is not working</Text>
      <FlatList
        data={data}
        renderItem={({ item }) => (
          <Pressable
            onPress={() => {
              data.pop(); // Does not work because we are not changing it's ref
            }}
            style={{ backgroundColor: item, padding: 8 }}>
            <Text>{item}</Text>
          </Pressable>
        )}
      />
    </>
  );
};

data 需要一个新的数组引用,如下所示。 data2.filter(..) 将 return 一个新数组,我们不会更改 data2 基值,只是创建一个少了一项的新数组。


const MyList = () => {
  const [data2, setData2] = React.useState([
    '#00FFFF',
    '#0080FF',
    '#0000FF',
  ]);

  return (
    <>
      <Text>List WORKING!</Text>
      <FlatList
        data={data2}
        renderItem={({ item }) => (
          <Pressable
            onPress={() => {
              setData2(data2.filter(dataItem => dataItem !== item)) // works

              //setData2([]); // Also works
            }}
            style={{ backgroundColor: item, padding: 8 }}>
            <Text>{item}</Text>
          </Pressable>
        )}
      />
    </>
  );
};

Immer.js 这样的库简化了状态操作以改变对象,immer 将为您创建一个新的引用。

哦,没有浪费大家时间的菜鸟错误!! 我正在实施停止 Flatlist 渲染的 shouldComponentUpdate 方法 :( 感谢大家的回答