简体   繁体   English

无法阻止 React.memo 重新渲染

[英]Fail to prevent re-render by React.memo

I am building a react native app for which has a form page contains a lot of textInput and buttons.我正在构建一个反应本机应用程序,其表单页面包含大量文本输入和按钮。 Each of fields do not causing performance issue.每个字段都不会导致性能问题。

However, when they are put together, the application will show js thread frame drops in the Perf Monitor.但是,当它们放在一起时,应用程序将在 Perf Monitor 中显示 js 线程帧丢失。 So I think the page is re-rendering all the components when any of the state is changed.因此,我认为当 state 中的任何一个发生更改时,页面都会重新呈现所有组件。

I tried 2 methods.我尝试了2种方法。

  1. Moving components out of the main export function.搬出主出口元器件 function。
  2. Using React.memo .使用React.memo

Unfortunately, both of them are not working.不幸的是,它们都不起作用。 The app still lag and re-render every time for all components.该应用程序仍然滞后并每次为所有组件重新呈现。

So I created a simple case for it.所以我为它创建了一个简单的案例。 You may see the code below.您可能会看到下面的代码。

I would like to only re-render the ChildItem for only the respective state changed.我只想为相应的 state 更改重新呈现ChildItem For now, console will log from 1 to 5 for any button clicked.现在,控制台将为单击的任何按钮记录 1 到 5。 Since the props passed to memo component is not changed, I expect the console will only log 1 respective sentence for specific index when button is pressed.由于传递给备忘录组件的props没有改变,我希望当按下按钮时,控制台只会为特定索引记录 1 个相应的句子。

import React, {useState, memo} from 'react';
import { View, Text, Button } from 'react-native';

const ChildeItem = memo( ({index, value, onPress}) =>{
  console.log(`ChildeItem ${index} rendered`);
  return(
    <View style={{flexDirection: 'row'}}>
      <Text style={{flex: 1, textAlign: 'center'}}>
        {value}
      </Text>
      <View style={{flex: 1}}>
        <Button 
          onPress={onPress} 
          title={"+"}
        />
      </View>
    </View>
  )
});

export default function TestScreen({navigation}) {
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);
  const [value3, setValue3] = useState(0);
  const [value4, setValue4] = useState(0);
  const [value5, setValue5] = useState(0);

  return(
    <View>
      <ChildeItem index={1} value={value1} onPress={()=>{setValue1(value1+1);}} />
      <ChildeItem index={2} value={value2} onPress={()=>{setValue2(value2+1);}} />
      <ChildeItem index={3} value={value3} onPress={()=>{setValue3(value3+1);}} />
      <ChildeItem index={4} value={value4} onPress={()=>{setValue4(value4+1);}} />
      <ChildeItem index={5} value={value5} onPress={()=>{setValue5(value5+1);}} />
    </View>
  )
}

Or I have any misunderstanding for React.memo ?或者我对React.memo有什么误解? Any help will be appreciated.任何帮助将不胜感激。 Thanks.谢谢。

Your index and value props are ok for memoization, but your onPress prop causes re-render because on every render of the TestScreen, your onPress prop functions are re-created, so it's reference changes.您的indexvalue道具可以用于记忆,但是您的onPress道具会导致重新渲染,因为在 TestScreen 的每次渲染中,都会重新创建您的 onPress 道具功能,因此它是参考更改。 You can prevent this by usinguseCallback hook.您可以使用useCallback挂钩来防止这种情况。

export default function TestScreen({navigation}) {
  const [value1, setValue1] = useState(0);
  const [value2, setValue2] = useState(0);
  const [value3, setValue3] = useState(0);
  const [value4, setValue4] = useState(0);
  const [value5, setValue5] = useState(0);

  // Use useCallback for each function
  const onPress1 = useCallback(() => setValue1(value1+1), [value1]);
  const onPress2 = useCallback(() => setValue2(value2+1), [value2]);
  const onPress3 = useCallback(() => setValue3(value3+1), [value3]);
  const onPress4 = useCallback(() => setValue4(value4+1), [value4]);
  const onPress5 = useCallback(() => setValue5(value5+1), [value5]);

  return(
    <View>
      <ChildeItem index={1} value={value1} onPress={onPress1} />
      <ChildeItem index={2} value={value2} onPress={onPress2} />
      <ChildeItem index={3} value={value3} onPress={onPress3} />
      <ChildeItem index={4} value={value4} onPress={onPress4} />
      <ChildeItem index={5} value={value5} onPress={onPress5} />
    </View>
  )
}

By using useCallback hook, you're memoizing the onPress functions, so they are re-created only when the relevant value changes.通过使用useCallback挂钩,您正在记住 onPress 函数,因此只有当相关值发生变化时才会重新创建它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在功能组件中使用 React.memo 来渲染 Item FlatList 以最小化重新渲染现有项目 - using React.memo in functional component to renderItem FlatList to minimize re-render existing items Unbale 以防止使用 useCallback 和 React.memo 重新渲染 - Unbale to prevent re rendering using useCallback and React.memo 防止子组件在带有备忘录的上下文提供程序下重新渲染 - prevent child component to re-render below context provider with memo React.memo 和 typescript - React.memo and typescript 即使使用 React.memo 也会重新渲染 FlatList 项目 - FlatList items re-rendering even with React.memo React.memo 阻止渲染 redux 嵌套数据不起作用 - React.memo prevent rendering redux nested data doesnt work 防止针对React Router参数的每个URI重新呈现 - Prevent re-render with every URI for React Router params 重组纯或React.memo吗? - recompose pure or React.memo? React Native - FlatLists 重新呈现记忆化组件(React.memo 不起作用) - React Native - FlatLists re-renders memoized components (React.memo not working) React Native 如何在集合中的每个组件上使用 React.memo 以仅渲染更改的组件。 React.memo 的奇怪行为 - React Native how to use React.memo on every component from collection to render only changed ones. Strange behavior of React.memo
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM