1

当其中一项发生更改时,我的 FlatListrenderItem正在重新渲染每个项目。
在做了一些调试之后,我对保存项目 (+ React.memo) 的状态变量进行了深度克隆,它现在工作正常,但不确定它是否是最佳解决方案。

小吃: https ://snack.expo.io/-419PhiUl

应用程序.js

import * as React from 'react';
import { View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
import _ from 'lodash';

import Item from './components/Item';

const keyExtractor = item => item.id.toString();

export default function App() {
  const [data, setData] = React.useState([
    {id: 1, title: 'Post 1', liked: false, user: {name: 'A'}},
    {id: 2, title: 'Post 2', liked: false, user: {name: 'B'}},
    {id: 3, title: 'Post 3', liked: false, user: {name: 'C'}},
  ]);

  /**
   * Like / Unlike the item.
  */
  const like = React.useCallback((id) => {
    setData(state => {
      let clonedState = [...state];
      let index = clonedState.findIndex(item => item.id === id);

          clonedState[index].liked = ! clonedState[index].liked;

      return clonedState;
    });
  }, []);

  /**
   * Render items.
  */
  const renderItem = React.useCallback(({item}) => (
    <Item item={item} onLike={like} />
  ), []);

  const deepClonedData = React.useMemo(() => _.cloneDeep(data), [data]);

  return (
    <View style={styles.container}>
      <FlatList
        data={deepClonedData}
        renderItem={renderItem}
        keyExtractor={keyExtractor}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  }
});

项目.js

import React from 'react';
import {
  Text, TouchableOpacity, StyleSheet
} from 'react-native';

function Item({item, onLike}) {
  const _onLike = React.useCallback(() => {
    onLike(item.id);
  }, []);

  console.log('rendering', item.title);

  return (
    <TouchableOpacity onPress={_onLike} style={styles.item}>
      <Text>{item.title} : {item.liked ? 'liked' : 'not liked'}</Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  item: {
    marginVertical: 10,
    backgroundColor: 'white',
    padding: 15,
    borderWidth: 1
  }
});

const areEqual = (prevProps, nextProps) => {
  return prevProps.item.liked === nextProps.item.liked;
}

export default React.memo(Item, areEqual);
4

0 回答 0