React Native 防止子进程重新渲染

问题描述 投票:0回答:1

我尝试了 useCallback 和 useMemo 的一堆不同变体,以及 React.memo,但它没有我想要的行为,有人可以帮助我吗? 问题是,每当父级的状态发生变化时(例如当我将手机转向侧面时,或者当“isShown”更改时),它都会重新渲染子级并重新触发读取数据功能,这不仅浪费数据,因为它会导致再次调用后端,但用户还必须等待再次获取数据。 有没有办法在每次重新渲染父级时不重新触发子级的handleReadData?

家长:

export default function Parent({}) {

const [isShown, setIsShown] = React.useState(false);

{...}

const WifiModuleSection = ({title, wifiModule, wifiSection}) => {
    return (
      <View style={styles.sectionWifiModuleContainer}>
          <View>
            {...}
          </View>
          <WifiModuleControls wifiModule={wifiModule} t={t} i18n={i18n} />
        </View>
    );
  };

return return (
                    <View>
                      {isShown &&
                        WifiModules.map(wifiModule => {
                          return (
                            <WifiModuleSection
                              title={wifiModule.name}
                              wifiModule={wifiModule}
                              wifiSection={wifiSection}
                            />
                          );
                        })}
                      {...}
                    </View>
                );
}

孩子:

const WifiModuleControls = ({wifiModule, t, i18n}) => {

{...}

const handleReadData = async () => {
    //Request Read state-data
    try {
      setLoadingReadData(true);
      const formData = {...};
      const res = await client.post('/read-data', formData);

      if (res.data.success) {
        {...}
        setData(res.data.data);
        setLoadingReadData(false);
      } else {
        Toast.showShortBottom('Error: ' + res.data.message);
        setLoadingReadData(false);
      }
    } catch (error) {
      Toast.showShortBottom('Error : ' + error);
      setLoadingReadData(false);
    }
  };

  useEffect(() => {
      handleReadData();
  }, []);

if (loadingReadData) {
    return (
      <ActivityIndicator
        style={{marginBottom: 1}}
        color={currentMainThemeColor}
        size={60}
      />
    );
  }

 return (
    <View>
    {...}
    </View>
 );
};

export default WifiModuleControls;

我简化了代码,仅显示相关部分

react-native
1个回答
0
投票

这并不是为了防止重新渲染。要么是关于:

  1. 防止“重新安装”或
  2. 缓存数据或
  3. 提升状态(类似于2,但不完全相同)

问题是

WifiModuleControls
拥有数据的获取和状态保存,因此当它卸载时,该数据就会“丢失”,取回数据的唯一方法是在组件安装时重新获取它。

发生这种情况是因为这一行:

                      {isShown &&
                        WifiModules.map(wifiModule => {
                          return (
                            <WifiModuleSection
                              title={wifiModule.name}
                              wifiModule={wifiModule}
                              wifiSection={wifiSection}
                            />
                          );
                        })}

如果

isShown
为假,则组件卸载,数据消失。

您可以采取多种措施来解决您的问题:

  1. 始终保持组件已安装,只是可能使其不可见
  2. 将获取和状态移至父组件,并将获取的数据传递到
    WifiModuleSection
    。这样,当
    WifiModuleSection
    卸载时,数据仍然保存在父组件中。
  3. 缓存获取的数据 - 这是像 useSWRtanstack-query 这样的库最耀眼的地方。
© www.soinside.com 2019 - 2024. All rights reserved.