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