首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React本机列表项备忘

React本机列表项备忘
EN

Stack Overflow用户
提问于 2019-10-06 22:00:22
回答 1查看 391关注 0票数 1

我试图使用React.memo()阻止不必要的FlatList项目渲染,但我遇到了一些奇怪的行为。提供前一个道具和下一个道具的回调始终具有相同的值,即使它们在链的更高位置发生了更改。

代码语言:javascript
复制
export default React.memo(PersonCell, (prev, next) => {
  reactotron.log(`prev ${prev.person.name}: is checked${prev.person.isChecked}`)
  reactotron.log(`next ${next.person.name}: is checked${next.person.isChecked}`)
  return prev.person.isChecked === next.person.isChecked
})

我拥有的链条是,我使用具有非常简单的{id:number, name:string, isChecked:boolean}结构的Realm,每当他们点击单元时,它就会写入realm,在应用程序的顶层,我有一个侦听器来监听数据更改,然后设置状态以将其向下传播到列表

代码语言:javascript
复制
let [data, setData] = useState([]);

  useEffect(() => {
    let sub = person$.subscribe({
      next: collection => {
        reactotron.logImportant!(collection)
        setData([...data, ...collection.map(x => x)]);
      },
    });

这是单元格代码

代码语言:javascript
复制
import React from 'react';
import { Subject } from "rxjs";
import { useEffect } from "react";
import realm, { PersonSchema } from "./realm";
import { Person } from "./PersonsList";
import { View, TouchableOpacity, Text } from "react-native";
import reactotron from 'reactotron-react-native';

interface Props {
  person: Person
}
const onCheck$ = new Subject<number>();
const PersonCell: React.FC<Props> = props => {

  useEffect(() => {
    let sub = onCheck$.subscribe({
      next: x => {
        realm.write(() => {
          let person = realm.objectForPrimaryKey<Person>(PersonSchema.name, x);
          if (!person) return;
          person.isChecked = !person.isChecked;
        });
      },
    });
    return () => sub.unsubscribe;
  }, []);

  return (
    <View>
      <Text>{props.person.name}</Text>
      <TouchableOpacity onPress={() => onCheck$.next(props.person.id)}>
        <View
          style={{
            backgroundColor: props.person.isChecked
              ? 'rgb(255,1,1)'
              : 'rgb(1,1,255)',
            width: 20,
            height: 20,
          }}
        />
      </TouchableOpacity>
    </View>
  );
};

PersonCell.whyDidYouRender = true;

// export default React.memo(PersonCell)
export default React.memo(PersonCell, (prev, next) => {
  reactotron.log(`prev ${prev.person.name}: is checked${prev.person.isChecked}`)
  reactotron.log(`next ${next.person.name}: is checked${next.person.isChecked}`)
  return prev.person.isChecked === next.person.isChecked
})

这是意料之中的行为,还是我做错了什么?Here is a repo我正在解释

更新

我删除了平面列表,并使用基本的映射和键来生成项目列表,上面的问题仍然出现在当前的属性中,传入的属性在shouldComponentUpdateReact.memo第二个参数中仍然是完全相同的,尽管已经改变了。

经历类似事情的人的here is a link

EN

回答 1

Stack Overflow用户

发布于 2019-10-09 00:34:10

我认为这个问题是由于非react方式的状态变化造成的。我相信这一点

代码语言:javascript
复制
let sub = person$.subscribe({
      next: collection => {
        setData(collection.map(x => x));
      },
    });

已经足够返回一个新的数组(因为map返回一个全新的数组)来使用所需的更改比较来更新状态。但显然,您需要执行以下操作。

代码语言:javascript
复制
let sub = person$.subscribe({
      next: collection => {
        setData(collection.map(x => x).map(x => _.toPlainObject(x)));
      },
    });

也就是说,对从realm返回的每个对象进行深度克隆,这样它才能工作,correctly...Or也许typescript有问题。

如果有人想用一个更简洁的答案插话,我们非常欢迎。

无论哪种方式,如果任何人想要查看它,repo都已经更新了这些更改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58257979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档