问题描述
我是 nextjs 新手,使用 nextjs v9.3
、next-redux-wrapper v5
、@material-ui/core v4.2
,以及自定义快递服务器
.
我正在尝试在 Nextjs 应用程序中更改路线时实现加载屏幕,因此我正在使用 framer 运动 用于页面之间的转换并且工作正常,但现在更改路线时如何使用加载组件?
我用了这些方法,但是没用:
我目前的实现如下:
_app.js
import React, { useEffect } from "react";从@material-ui/core/styles"导入 { ThemeProvider };从@material-ui/core"导入 { CssBaseline };从../lib/theme"导入{主题};从next-redux-wrapper"导入 withRedux;从react-redux"导入 { Provider };从../store/store"导入reduxStore;从redux-persist/integration/react"导入 { PersistGate };从framer-motion"导入{ AnimatePresence };从../components/Navbar"导入导航栏;从../components/Meta"导入 Meta;功能我的应用程序(道具){使用效果(() => {const jssStyles = document.querySelector("#jss-server-side");if (jssStyles && jssStyles.parentNode)jssStyles.parentNode.removeChild(jssStyles);}, []);const { 组件,pageProps,商店,路由器 } = 道具;返回 (<ThemeProvider 主题={主题}><Css基线/><提供者商店={商店}><PersistGate 持久化器={store.__PERSISTOR} loading={null}><元/><导航栏 {...props}/><AnimatePresence exitBeforeEnter><组件 {...pageProps} key={router.route}/></AnimatePresence></PersistGate></提供者></主题提供者>);}使用Redux(reduxStore)(MyApp)导出默认值;
更新
`___-_-_-_-_我的解决方案_-_-_-_-___`
方法1:在next.js v9.3中我使用framer-motion
导入反应,{使用效果,使用状态,} 来自反应";从@material-ui/core/styles"导入{ ThemeProvider as MaterialThemeProvider };从styled-components"导入{ ThemeProvider as StyledThemeProvider };从@material-ui/core"导入 { CssBaseline };从framer-motion"导入{ AnimatePresence,motion };从../lib/theme"导入主题;从../components/Layout"导入布局;从react-loader-spinner"导入加载器;功能我的应用程序(道具){const { 组件,pageProps,路由器 } = 道具;//打击 useState &useEffect 用于跟踪更改路线常量 [isRouteChanging, setIsRouteChanging] = useState(false);使用效果(() => {const routeChangeStartHandler = () =>setIsRouteChanging(true);const routeChangeEndHandler = () =>setIsRouteChanging(false);router.events.on(routeChangeStart", routeChangeStartHandler);router.events.on(routeChangeComplete", routeChangeEndHandler);router.events.on(routeChangeError", routeChangeEndHandler);返回()=>{router.events.off(routeChangeStart", routeChangeStartHandler);router.events.off(routeChangeComplete", routeChangeEndHandler);router.events.off(routeChangeError", routeChangeEndHandler);};}, []);//useEffect config material-ui使用效果(() => {//移除服务端注入的 CSS.const jssStyles = document.querySelector("#jss-server-side");if (jssStyles && jssStyles.parentNode)jssStyles.parentNode.removeChild(jssStyles);}, []);返回 (<StyledThemeProvider 主题={主题}><MaterialThemeProvider 主题={主题}><Css基线/>{/*当路由改变时每个页面的动画*/}<布局>{isRouteChanging ?(
方法 2:在 next.js v10 中,我使用了nprogress":^0.2.0"
import React, { useEffect } from "react";从下一个/路由器"导入路由器;//MUI核心从@material-ui/core/CssBaseline"导入 CssBaseline;从@material-ui/core/styles"导入 { ThemeProvider };//实用程序从Utils/theme"导入主题;//NProgress从nprogress"导入 NProgress;//绑定事件.Router.events.on(routeChangeStart", () => NProgress.start());Router.events.on(routeChangeComplete", () => NProgress.done());Router.events.on(routeChangeError", () => NProgress.done());功能 MyApp({ 组件, pageProps}) {//useEffect config material-ui使用效果(() => {//移除服务端注入的 CSS.const jssStyles = document.querySelector("#jss-server-side");if (jssStyles && jssStyles.parentNode)jssStyles.parentNode.removeChild(jssStyles);}, []);返回 (<提供者商店={商店}><ThemeProvider 主题={主题}><Css基线/><组件 {...pageProps}/></主题提供者></提供者>);}导出默认 MyApp;
我就是这样弄的.在 _app.tsx
中:
import { useRouter } from 'next/router';常量 MyApp = ({主要组件,页面道具,}) =>{常量路由器 = useRouter();const [pageLoading, setPageLoading] = React.useState(false);React.useEffect(() => {常量句柄开始 = () =>{ setPageLoading(true);};常量句柄完成 = () =>{ setPageLoading(false);};router.events.on('routeChangeStart', handleStart);router.events.on('routeChangeComplete', handleComplete);router.events.on('routeChangeError', handleComplete);}, [路由器]);返回 (...{ 页面加载?(<div>加载中</div>): <MainComponent {...pageProps}/>}...)}
I am new in nextjs and using nextjs v9.3
, next-redux-wrapper v5
, @material-ui/core v4.2
, and custom express server
.
I am trying to implement a loading screen when changing routes in my Nextjs app so I am using framer motion for transition between page and works fine but now how can use loading component when changing routes?
I used these methods but it didn't work :
My current implementation is as follows:
_app.js
import React, { useEffect } from "react";
import { ThemeProvider } from "@material-ui/core/styles";
import { CssBaseline } from "@material-ui/core";
import { theme } from "../lib/theme";
import withRedux from "next-redux-wrapper";
import { Provider } from "react-redux";
import reduxStore from "../store/store";
import { PersistGate } from "redux-persist/integration/react";
import { AnimatePresence } from "framer-motion";
import Navbar from "../components/Navbar";
import Meta from "../components/Meta";
function MyApp(props) {
useEffect(() => {
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles && jssStyles.parentNode)
jssStyles.parentNode.removeChild(jssStyles);
}, []);
const { Component, pageProps, store, router } = props;
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Provider store={store}>
<PersistGate persistor={store.__PERSISTOR} loading={null}>
<Meta/>
<Navbar {...props} />
<AnimatePresence exitBeforeEnter>
<Component {...pageProps} key={router.route}/>
</AnimatePresence>
</PersistGate>
</Provider>
</ThemeProvider>
);
}
export default withRedux(reduxStore)(MyApp);
`___-_-_-_-_my solution_-_-_-_-___`
method 1 : in next.js v9.3 when I used framer-motion
import React, {
useEffect,
useState,
} from "react";
import { ThemeProvider as MaterialThemeProvider } from "@material-ui/core/styles";
import { ThemeProvider as StyledThemeProvider } from "styled-components";
import { CssBaseline } from "@material-ui/core";
import { AnimatePresence, motion } from "framer-motion";
import theme from "../lib/theme";
import Layout from "../components/Layout";
import Loader from "react-loader-spinner";
function MyApp(props) {
const { Component, pageProps, router } = props;
// blow useState & useEffect for tracking change route
const [isRouteChanging, setIsRouteChanging] = useState(false);
useEffect(() => {
const routeChangeStartHandler = () => setIsRouteChanging(true);
const routeChangeEndHandler = () => setIsRouteChanging(false);
router.events.on("routeChangeStart", routeChangeStartHandler);
router.events.on("routeChangeComplete", routeChangeEndHandler);
router.events.on("routeChangeError", routeChangeEndHandler);
return () => {
router.events.off("routeChangeStart", routeChangeStartHandler);
router.events.off("routeChangeComplete", routeChangeEndHandler);
router.events.off("routeChangeError", routeChangeEndHandler);
};
}, []);
// useEffect config material-ui
useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles && jssStyles.parentNode)
jssStyles.parentNode.removeChild(jssStyles);
}, []);
return (
<StyledThemeProvider theme={theme}>
<MaterialThemeProvider theme={theme}>
<CssBaseline />
{/*animation for each page when route changes*/}
<Layout>
{isRouteChanging ? (
<motion.div
initial={{
opacity: 0,
height: "90vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
animate={{
opacity: 1,
}}
exit={{
opacity: 0,
}}
>
<Loader
type="Grid"
color={theme.spinnerColor}
height={80}
width={80}
/>
</motion.div>
) : (
<AnimatePresence exitBeforeEnter>
<Component {...pageProps} key={router.route} />
</AnimatePresence>
)}
</Layout>
</MaterialThemeProvider>
</StyledThemeProvider>
);
}
export default MyApp;
method 2 : in next.js v10 I used "nprogress": "^0.2.0"
import React, { useEffect } from "react";
import Router from "next/router";
// MUI Core
import CssBaseline from "@material-ui/core/CssBaseline";
import { ThemeProvider } from "@material-ui/core/styles";
// Utils
import theme from "Utils/theme";
// NProgress
import NProgress from "nprogress";
//Binding events.
Router.events.on("routeChangeStart", () => NProgress.start());
Router.events.on("routeChangeComplete", () => NProgress.done());
Router.events.on("routeChangeError", () => NProgress.done());
function MyApp({ Component, pageProps}) {
// useEffect config material-ui
useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector("#jss-server-side");
if (jssStyles && jssStyles.parentNode)
jssStyles.parentNode.removeChild(jssStyles);
}, []);
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</Provider>
);
}
export default MyApp;
I did it in this way. In _app.tsx
:
import { useRouter } from 'next/router';
const MyApp = ({
MainComponent,
pageProps,
}) => {
const router = useRouter();
const [pageLoading, setPageLoading] = React.useState<boolean>(false);
React.useEffect(() => {
const handleStart = () => { setPageLoading(true); };
const handleComplete = () => { setPageLoading(false); };
router.events.on('routeChangeStart', handleStart);
router.events.on('routeChangeComplete', handleComplete);
router.events.on('routeChangeError', handleComplete);
}, [router]);
return (
...
{ pageLoading
? (<div>Loading</div>)
: <MainComponent {...pageProps} />
}
...
)
}
这篇关于如何在 Next.js 中实现加载屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!