Если вы переместите const Memo = React.memo(Child, () => true)
за пределы ChildContainer
, ваш код будет работать должным образом.
Хотя ChildContainer
не является мемоизированным компонентом, он будет повторно отрисован и создаст мемоизированный Child
компонент при каждом повторном рендеринге родителя.
Перемещая мемоизацию за пределы ChildContainer
, вы безопасно запоминаете свой компонент Child
один раз, и независимо от того, сколько раз будет вызываться ChildContainer
, Child
будет выполняться только один раз.
Вот рабочая демка . Я также добавил журнал на App
для отслеживания каждого повторного рендеринга и один журнал в ChildComponent
, чтобы вы могли видеть, что эта функция вызывается при каждом повторном рендеринге, не касаясь больше Child
.
Вы также можете заключить Child
в React.memo
напрямую:
import * as React from "react";
import { Text, View, StyleSheet } from "react-native";
// or any pure javascript modules available in npm
let interval = null;
const Child = React.memo(({ name }) => {
//Why would this child still rerender, and how to prevent it?
console.log("memoized component rerender");
return <Text>{name}</Text>;
}, () => true);
const ChildContainer = ({ name }) => {
console.log("ChildContainer component rerender");
return <Child name={name} />;
};
export default function App() {
const [state, setState] = React.useState(0);
const name = "constant";
// Change the state every second
React.useEffect(() => {
interval = setInterval(() => setState(s => s + 1), 1000);
return () => clearInterval(interval);
}, []);
console.log("App rerender");
return (
<View>
<ChildContainer name={name} />
</View>
);
}