渲染后未调用React Native useEffect(使用适当的依赖项)

时间:2019-08-18 17:37:50

标签: react-native use-effect

我对useEffect在网络和移动设备中的不同行为感到惊讶。渲染组件后,我希望调用useEffect。它确实在网络上。请参见以下代码段: https://codesandbox.io/s/react-hooks-usestate-and-useeffect-m20dv?fontsize=14

我也在这里发布了代码,供您乍看。

import React, { useState, useEffect, useCallback } from "react";
import ReactDOM from "react-dom";

function useAttemptToSaveCapture() {
  const [shouldCheckPermission, setShouldCheckPermissionFlag] = useState(false);

  console.log("shouldCheckPermission", shouldCheckPermission);

  useEffect(() => {
    console.log("Running AttemptToSaveCapture Effect!");
    return () => console.log("cleaning effect...");
  }, [shouldCheckPermission]);

  return { setShouldCheckPermissionFlag };
}

function useCapture() {
  const { setShouldCheckPermissionFlag } = useAttemptToSaveCapture();

  const onSaveCapture = useCallback(() => {
    console.log("-----------------");
    console.log("button clicked...");

    setShouldCheckPermissionFlag(true);
  }, [setShouldCheckPermissionFlag]);

  return { onSaveCapture };
}

function App() {
  console.log("rendering...");
  const { onSaveCapture } = useCapture();

  return <button onClick={onSaveCapture}>content</button>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

因此,重要的代码是以下代码段:

useEffect(() => {
    console.log("Running AttemptToSaveCapture Effect!");
    return () => console.log("cleaning effect...");
  }, [shouldCheckPermission]);

正如我所说,在Web上运行此代码段可获得预期的结果:单击按钮后调用useEffect,因为这会触发重新渲染。但是 React Native 中的相同代码不会。或者,实际上,它会在大约30秒后(当我的手机变暗以节省能量时)。

除视图标签外,代码相同,请参见:

import React, {Fragment, useState, useCallback, useRef, useEffect} from 'react';
import {PermissionsAndroid, StyleSheet, Button, View, Text} from 'react-native';

function useAttemptToSaveCapture() {
  const [shouldCheckPermission, setShouldCheckPermissionFlag] = useState(false);

  console.log('shouldCheckPermission', shouldCheckPermission);

  useEffect(() => {
    console.log('Running AttemptToSaveCapture Effect!');
    return () => console.log('cleaning effect...');
  }, [shouldCheckPermission]);

  return {setShouldCheckPermissionFlag};
}

function useCapture() {
  const {setShouldCheckPermissionFlag} = useAttemptToSaveCapture();

  const onSaveCapture = useCallback(() => {
    console.log('-----------------');
    console.log('button clicked...');

    setShouldCheckPermissionFlag(true);
  }, [setShouldCheckPermissionFlag]);

  return {onSaveCapture};
}

function App() {
  console.log('rendering...');
  const {onSaveCapture} = useCapture();

  return (
    <Fragment>
      <Button onPress={onSaveCapture} title="Save" />
      <View style={styles.capture}>
        <Text style={styles.content}>Capture</Text>
      </View>
    </Fragment>
  );
}

const styles = StyleSheet.create({
  capture: {
    flex: 1,
    backgroundColor: '#313131',
    justifyContent: 'center',
    alignItems: 'center',
  },
  content: {
    color: 'white',
    fontSize: 40,
  },
});

export default App;

我所读过的所有有关钩子的内容都可以确保我的代码正常工作。另一方面,我发现有关React Native的所有示例都是使用生命周期方法的示例。也许钩子还没有被用于本地反应?我找不到这种行为不一致的解释。有什么线索吗?


更新:我发现它还可以与AVD和小吃片段https://snack.expo.io/SkuxEfPNr一起使用。只是不能在真正的手机上使用。

0 个答案:

没有答案