Я пытаюсь предотвратить ненужные отрисовки FlatList
элементов, используя React.memo()
, но я столкнулся с некоторым странным поведением. обратный вызов, который обеспечивает предыдущие реквизиты и последующие реквизиты, всегда имеет одинаковое значение, даже если они изменились выше по цепочке.
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
})
Цепочка, которую я имею, я использую Realm
с оченьпростая структура {id:number, name:string, isChecked:boolean}
и всякий раз, когда они касаются ячейки, она будет записывать в область, на верхнем уровне приложения у меня есть прослушиватель изменений данных, а затем устанавливается состояние для передачи его обратно в список
let [data, setData] = useState([]);
useEffect(() => {
let sub = person$.subscribe({
next: collection => {
reactotron.logImportant!(collection)
setData([...data, ...collection.map(x => x)]);
},
});
вот код клетки
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
})
Это ожидаемое поведение или я что-то не так делаю? Вот репо того, что я объясняю
Обновление
Я удалил плоский список и использовал базовую карту и ключ, чтобы сгенерировать список предметов, и проблема выше по-прежнемуПоявились текущие реквизиты, а переданные реквизиты во втором параметре shouldComponentUpdate
и React.memo
остались прежними, несмотря на их изменение.
здесь есть ссылка изпарень испытывает нечто подобное