我使用React Native。运行它时出现此错误:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See for tips about how to debug and fix this problem.
This error is located at:
in App (at renderApplication.js:45)
in RCTView (at AppContainer.js:109)
in RCTView (at AppContainer.js:135)
in AppContainer (at renderApplication.js:39)
throwInvalidHookError
ReactNativeRenderer-dev.js:10884:15
render
App.js:70:34
finishClassComponent
ReactNativeRenderer-dev.js:13591:21
updateClassComponent
ReactNativeRenderer-dev.js:13516:43
invokeGuardedCallbackImpl
ReactNativeRenderer-dev.js:286:4
invokeGuardedCallback
ReactNativeRenderer-dev.js:497:2
beginWork$$1
ReactNativeRenderer-dev.js:22028:27
performUnitOfWork
ReactNativeRenderer-dev.js:20871:23
workLoopSync
ReactNativeRenderer-dev.js:20848:38
performSyncWorkOnRoot
ReactNativeRenderer-dev.js:20456:22
performSyncWorkOnRoot
[native code]:0
runWithPriority$argument_1
ReactNativeRenderer-dev.js:5703:31
unstable_runWithPriority
scheduler.development.js:818:23
flushSyncCallbackQueueImpl
ReactNativeRenderer-dev.js:5698:21
flushSyncCallbackQueue
ReactNativeRenderer-dev.js:5686:28
scheduleUpdateOnFiber
ReactNativeRenderer-dev.js:19845:30
updateContainer
ReactNativeRenderer-dev.js:23608:14
ReactNativeRenderer.render
ReactNativeRenderer-dev.js:24593:19
renderApplication
renderApplication.js:54:4
runnables.appKey.run
AppRegistry.js:117:25
runApplication
AppRegistry.js:202:4
__callFunction
MessageQueue.js:425:19
__guard$argument_0
MessageQueue.js:112:6
__guard
MessageQueue.js:373:10
callFunctionReturnFlushedQueue
MessageQueue.js:111:4
callFunctionReturnFlushedQueue
[native code]:0
问题是
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsLoaded(true);
}, 1000);
}, []);
当我删除它时,它运行良好。我应该在哪里或如何编写该代码?
我的完整脚本是:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, { Component, useState, useEffect } from 'react';
import OneSignal from 'react-native-onesignal';
import { StyleSheet, StatusBar, SafeAreaView, BackHandler, View } from 'react-native';
import { WebView } from 'react-native-webview';
import AnimatedSplash from "./lib/AnimatedSplash";
class App extends Component {
constructor(props) {
super(props);
OneSignal.setLogLevel(6, 0);
OneSignal.init("MYAPPID", {kOSSettingsKeyAutoPrompt : false, kOSSettingsKeyInAppLaunchURL: false, kOSSettingsKeyInFocusDisplayOption:2});
OneSignal.inFocusDisplaying(2); // Controls what should happen if a notification is received while the app is open. 2 means that the notification will go directly to the device's notification center.
// The promptForPushNotifications function code will show the iOS push notification prompt. We recommend removing the following code and instead using an In-App Message to prompt for notification permission (See step below)
OneSignal.promptForPushNotificationsWithUserResponse(myiOSPromptCallback);
OneSignal.addEventListener('received', this.onReceived);
OneSignal.addEventListener('opened', this.onOpened);
OneSignal.addEventListener('ids', this.onIds);
}
componentWillUnmount() {
OneSignal.removeEventListener('received', this.onReceived);
OneSignal.removeEventListener('opened', this.onOpened);
OneSignal.removeEventListener('ids', this.onIds);
}
onReceived(notification) {
console.log("Notification received: ", notification);
}
onOpened(openResult) {
console.log('Message: ', openResult.notification.payload.body);
console.log('Data: ', openResult.notification.payload.additionalData);
console.log('isActive: ', openResult.notification.isAppInFocus);
console.log('openResult: ', openResult);
}
onIds(device) {
console.log('Device info: ', device);
}
webView = {
canGoBack: false,
ref: null,
}
onAndroidBackPress = () => {
if (this.webView.canGoBack && this.webView.ref) {
this.webView.ref.goBack();
return true;
}
return false;
}
componentWillMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('hardwareBackPress', this.onAndroidBackPress);
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackHandler.removeEventListener('hardwareBackPress');
}
}
render() {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setTimeout(() => {
setIsLoaded(true);
}, 1000);
}, []);
return (
<AnimatedSplash
logoWidht={150}
logoHeight={150}
isLoaded={isLoaded}
backgroundColor={"#262626"}
logoImage={require("./assets/logo.png")}
>
<View style={ styles.styleNew }>
<SafeAreaView style={styles.safearea}/>
<StatusBar barStyle="light-content"/>
<WebView
source={{ uri: 'https://myweb.com' }}
hideKeyboardAccessoryView={true}
javaScriptEnabled={true}
domStorageEnabled={true}
allowsInlineMediaPlayback={true}
allowsFullscreenVideo={true}
contentInsetAdjustmentBehavior={'always'}
allowsBackForwardNavigationGestures={true}
ref={(webView) => { this.webView.ref = webView; }}
onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack; }}
></WebView>
</View>
</AnimatedSplash>
);
}
}
function myiOSPromptCallback(permission){
// do something with permission value
}
const styles = StyleSheet.create({
styleNew: {
backgroundColor: 'white',
flex: 1,
},
safearea: {
backgroundColor: '#1e2321',
flex: 0,
},
WebViewStyle: {
justifyContent: 'center',
alignItems: 'center',
flex: 1,
marginTop: 40,
},
});
export default App;