I start learning react about 2 month ago. Right now I am trying to build my portfolio with some interactive design using spline 3d. The problem is the loading time is too long and I want to make a loading screen that stop loading exact time when my 3d start element render
I start learning react about 2 month ago. Right now I am trying to build my portfolio with some interactive design using spline 3d. The problem is the loading time is too long and I want to make a loading screen that stop loading exact time when my 3d start element render
Share Improve this question edited Aug 5, 2022 at 16:38 Htet Ah Yan asked Aug 5, 2022 at 16:03 Htet Ah YanHtet Ah Yan 451 gold badge1 silver badge3 bronze badges 4- Hi @Htet, you will get more quality help if you can improve the quality of your question, see: stackoverflow./help/how-to-ask – JBaczuk Commented Aug 5, 2022 at 16:06
-
This doesn't have anything to do with
react-router
actually. Just use some localisLoading
ponent state and conditionally render a loading indicator. If you need help further then please edit your post to include a minimal reproducible example for what you've tried so far and provide details on any issues. – Drew Reese Commented Aug 5, 2022 at 16:06 - @DrewReese Yes I did the same way but that doesn't affect any changes to my page, once the loading screen end my page loading still too long – Htet Ah Yan Commented Aug 5, 2022 at 16:27
- Then I'd say you've not implemented it correctly. Please share an actual code example so we can see what the code is doing and why it may not be working as expected. – Drew Reese Commented Aug 5, 2022 at 17:44
3 Answers
Reset to default 2I did the below and I'm pretty happy with it. This is for react router v6 with loader functions.
Note that the loading screen will be displayed only while the loader function is being executed. If you want to keep showing it after a route ponent is rendered and dismiss it from within the ponent you could pass the setLoaded
function as a prop to your ponent in the router configuration.
import React, { useState, useEffect } from 'react';
import {
createBrowserRouter,
Outlet,
RouterProvider,
} from 'react-router-dom';
// Have a function for creating your router so that you can pass
// a function as a prop to your page wrapper, in order for it to let
// you know when a page has loaded
const wireRouter = (setLoaded) => createBrowserRouter([
{
path: '/',
element: <PageWrapper setLoaded={setLoaded} />,
children: [
{
path: '/*',
element: <PageNotFound />,
},
{
path: '/',
element: <Home />,
},
{
path: '/pageThatLoadsSomething/',
element: <PageThatLoadsSomething />,
loader: () => functionThatLoadsSomething(),
}
]
}
]);
// In your page wrapper set loaded to true immediately after you render
function PageWrapper({ setLoaded }) {
useEffect(() => {
setLoaded(true);
}, []);
return <Outlet />;
}
// Make a root ponent that keeps state of whether a page is loaded
// and pass the setter to update it to the function that creates your
// router. Render a loader ponent conditionally, while the page is
// not loaded.
function Root() {
const [pageLoaded, setLoaded] = useState(false);
return (
<React.StrictMode>
{ !pageLoaded ? <Loading /> : null }
<RouterProvider router={wireRouter(setLoaded)} />
</React.StrictMode>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Root />);
There are multiple ways to create it by your self.
you can you use the library react-loader-spinner
on the console type npm install react-loader-spinner --save
import React from 'react';
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css";
import Loader from "react-loader-spinner";
import '../style.css';
const LoaderComponent = () => {
return (
<div className="loader">
<Loader
type="Circles"
color="#dc1c2c"
height={50}
width={100}
//timeout={1000} //3 secs
/>
</div>
);
};
export default LoaderComponent;
To display the ponent there are multiple ways, here is a way for GraphQL fetching data from the DB
const [results] = useQuery({ query: PRODUCT_QUERY });
const { data, fetching, error } = results;
//Check or the data ing in
if (fetching) return <p>Loading...</p>;
if (error) return <p>Oh no... {error.message}</p>;
Here is a way from fetching data with HTTP Request:
const UserList = () => {
const auth = useContext(AuthContext);
const { isLoading, error, sendRequest, clearError } = useHttpClient();
const [loadedUsers, setLoadedUsers] = useState();
useEffect(() => {
const fetchUsers = async () => {
try {
//with fetch, the default request type is GET request
const responseData = await sendRequest(
process.env.REACT_APP_BACKEND_URL + "/users"
);
setLoadedUsers(responseData.users); //users propeties is the given value from the backend (user-controllers.js on getUsers())
} catch (err) {}
};
fetchUsers();
}, [sendRequest]);
return (
<React.Fragment>
<ErrorModal error={error} onClear={clearError} />
{isLoading && <LoadingSpinner asOverlay />}
{/* we need to render loadedUsers only if not empty*/}
{!isLoading && loadedUsers && (
<div className="userList">
<span className="Title">Display Here the data</span>
</div>
)}
</React.Fragment>
);
};
// this logic is simple
// first, you have created one boolean usestate(false) and then load your screen that time usestate are true and process is plete after usesate are false
// I will show you the following example. I hope that helps you.
export default function Gradients(props) {
const [isLoading, setIsLoading] = useState(false);
const getAllGradient = () => {
setIsLoading(true);
axios
.get("https://localhost:5000")
.then((res) => {
const gradientColors = res.data;
// process plete after isLoading are false
// your process (this only example)
setIsLoading(false);
})
}
return(
<div>
{
isLoading ? <Loader> : <YourComponent />
}
</div>
)
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>