[英]Nextjs TypeScript useContext through the pages
I was not using我没有使用
import Link from 'next/link';
in my Header.tsx component.在我的Header.tsx组件中。
Now it works.现在它起作用了。
Don't know what I am doing wrong right here.不知道我在这里做错了什么。 I try to make global state (to indicate if user is logged in or not) that just flows through the pages and I try to do it with react's hook useContext.
我尝试创建仅流经页面的全局状态(以指示用户是否已登录),并尝试使用 react 的钩子 useContext 来实现。
It is not working like how I would like to make it work.它不像我想让它工作的方式工作。 When I toggleLogged and go to another page, the context has default value and not the changed one.
当我toggleLogged并转到另一个页面时,上下文具有默认值而不是更改的值。 I think the problem I am facing is something really small or a fundemantal thing that I just can't see.
我认为我面临的问题是一些非常小的或我无法看到的基本问题。
Here is how my UserContext.ts file looks:这是我的UserContext.ts文件的外观:
import { createContext, useContext } from 'react';
type userContextType = {
isLogged: boolean;
toggleLogged: () => void;
};
const userContextDefault: userContextType = {
isLogged: false,
toggleLogged: () => {},
};
export const UserContext = createContext(userContextDefault);
export function useUserContext() {
return useContext(UserContext);
}
Here is my Layout.tsx :这是我的Layout.tsx :
import React, { useState } from 'react';
import Header from './Header';
const Layout = (props: any) => {
const { children } = props;
return (
<div className='container'>
<Header />
{children}
</div>
);
};
export default Layout;
And lastly here is my _app.tsx :最后这里是我的_app.tsx :
import type { AppContext, AppProps } from 'next/app';
import Layout from '../components/Layout';
import { useState } from 'react';
import { UserContext } from '../components/UserContext';
import '../styles/globals.css';
const MyApp = ({ Component, pageProps }: AppProps) => {
const [isLogged, setIsLogged] = useState(true);
const toggleLogged = () => {
setIsLogged((isLogged) => !isLogged);
};
return (
<UserContext.Provider value={{ isLogged, toggleLogged }}>
<Layout>
<Component {...pageProps} />;
</Layout>
</UserContext.Provider>
);
};
export default MyApp;
Thanks for any help in advance.提前感谢您的任何帮助。
You need to return the provider in the context, and then reference the instance in _app.js.您需要在上下文中返回提供者,然后在 _app.js 中引用该实例。
Here's my AuthContext (as an example).这是我的 AuthContext(作为示例)。 Don't worry about the specific code, but use my implementation as the foundation, and you'll be up and running in no time!
不用担心具体的代码,但是以我的实现为基础,您很快就会启动并运行!
import { createContext, useContext, useEffect, useState } from 'react'
import { auth } from '../firebase'
const AuthContext = createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
function signOut() {
return auth.signOut();
}
function signUp(email, password) {
return auth.createUserWithEmailAndPassword(email, password)
}
function getUser() {
return auth.currentUser
}
function isAdmin() {
return auth.currentUser.getIdTokenResult()
.then((idTokenResult) => {
if (!!idTokenResult.claims.admin) {
return true
} else {
return false
}
})
}
function isEditor() {
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
getUser,
login,
signOut,
signUp
}
return (
<AuthContext.Provider value={value}>
{ !loading && children }
</AuthContext.Provider>
)
}
My _app.js file:我的 _app.js 文件:
import '../styles/globals.scss'
import { motion, AnimatePresence } from 'framer-motion'
import { useRouter } from 'next/router'
import Header from '../components/Header'
import Footer from '../components/Footer'
import { AuthProvider } from '../contexts/AuthContext'
import { CartProvider } from '../contexts/CartContext'
import { ThemeProvider } from '@material-ui/core'
import theme from '../styles/theme'
export default function App({ Component, pageProps }) {
const router = useRouter()
return(
<AnimatePresence exitBeforeEnter>
<CartProvider>
<AuthProvider>
<ThemeProvider theme={theme}>
<Header />
<motion.div key={router.pathname} className="main">
<Component { ...pageProps } />
<Footer />
</motion.div>
</ThemeProvider>
</AuthProvider>
</CartProvider>
</AnimatePresence>
)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.