簡體   English   中英

無法阻止 React.memo 重新渲染

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

我正在構建一個反應本機應用程序,其表單頁面包含大量文本輸入和按鈕。 每個字段都不會導致性能問題。

但是,當它們放在一起時,應用程序將在 Perf Monitor 中顯示 js 線程幀丟失。 因此,我認為當 state 中的任何一個發生更改時,頁面都會重新呈現所有組件。

我嘗試了2種方法。

  1. 搬出主出口元器件 function。
  2. 使用React.memo

不幸的是,它們都不起作用。 該應用程序仍然滯后並每次為所有組件重新呈現。

所以我為它創建了一個簡單的案例。 您可能會看到下面的代碼。

我只想為相應的 state 更改重新呈現ChildItem 現在,控制台將為單擊的任何按鈕記錄 1 到 5。 由於傳遞給備忘錄組件的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>
  )
}

或者我對React.memo有什么誤解? 任何幫助將不勝感激。 謝謝。

您的indexvalue道具可以用於記憶,但是您的onPress道具會導致重新渲染,因為在 TestScreen 的每次渲染中,都會重新創建您的 onPress 道具功能,因此它是參考更改。 您可以使用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>
  )
}

通過使用useCallback掛鈎,您正在記住 onPress 函數,因此只有當相關值發生變化時才會重新創建它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM