3

我对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 。它在真手机上是行不通的。

4

0 回答 0