Here I have a Loading screen as a functional react component that I try to render conditionally in the App component. The concept of this loading screen is that I have a boolean variable that will be used to conditionally render the home page after the loading screen ends.
import React from 'react'; import { useState, useEffect } from 'react'; import { useSpring, animated } from 'react-spring'; import BarLoader from 'react-spinners/BarLoader'; import Logo from "../assets/images/logo.svg"; const LoadingScreen = () => { const spinner = ` display: block; margin: 0 auto; width: 150px; height: 2.5px; `; const style = useSpring({opacity: 1, from: {opacity: 0}}); const [isLoading, setIsLoading] = useState(false); useEffect(() => { setIsLoading(true); setTimeout(() => { setIsLoading(false) }, 4000) }, []) const LoadingTemplate = () => { <animated.div className="loading-screen" style={style}> <div className="loader-wrapper"> <img className="splash-logo" src={Logo} alt="Marouane Edghoughi" /> <BarLoader color="#384BEB" css={ spinner } loading={isLoading} /> </div> </animated.div> } return { LoadingTemplate, isLoading } } export default LoadingScreen;
When I try to call the boolean variable and the screen template in the following code:
render() { const {LoadingTemplate, isLoading} = LoadingScreen(); return ( <Router> { isLoading? <LoadingTemplate />: <Container className="theme p-0" fluid={true}> {/* something will be displayed here */} </Container> } </Router> ); } }
I just get this error:
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:
The function is working properly if I try to call it from a functional component. This is my first time trying it with a class.
Any help would be greatly appreciated ^_^
The error message is 100% correct. Hooks can be used only in Function Components, and cannot be used like this in class components. The underlying mechanics of the two types are different. Hooks are a feature of functional components and rely on those mechanics, and are therefore not compatible with class components.
You may not realize that you are using a hook, but LoadingScreen
actually is one: It returns a value other than a React Element, and you are calling it as a function (ie const x = LoadingScreen()
), rather than using it as a component (ie <LoadingScreen />
).
That's definitely not allowed in class components. You could use a function component instead:
const Component = () => {
const {LoadingTemplate, isLoading} = LoadingScreen();
return (
<Router>
{
isLoading ?
<LoadingTemplate />
:
<Container className="theme p-0" fluid={true}>
{/* something will be displayed here */}
</Container>
}
</Router>
);
}
}
Or you can try these methods to get around this limitation. If you do decide to use a function component instead, then you should use useLoadingScreen
to follow the React hook naming conventions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.