Я использую 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;