【问题标题】:Nextjs TypeScript useContext through the pagesNextjs TypeScript useContext 通过页面
【发布时间】:2021-06-24 17:09:19
【问题描述】:

编辑:

我没有使用

import Link from 'next/link';

在我的 Header.tsx 组件中。

现在可以了。


不知道我在这里做错了什么。 我尝试创建仅流经页面的全局状态(以指示用户是否已登录),并尝试使用 react 的钩子 useContext 来实现。

它不像我想要的那样工作。当我 toggleLogged 并转到另一个页面时,上下文具有默认值,而不是更改后的值。 我认为我面临的问题是一些非常小的问题,或者是我无法看到的基本问题。

这是我的 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);
}

这是我的 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;

最后是我的_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;

提前感谢您的帮助。

【问题讨论】:

  • 您在哪里以及如何使用该上下文?

标签: javascript reactjs typescript next.js


【解决方案1】:

你需要返回提供者in上下文,然后在_app.js中引用实例。

这是我的 AuthContext(例如)。不用担心具体的代码,以我的实现为基础,你很快就能上手!

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>
  )

}

我的 _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>
  )
}

【讨论】:

  • 感谢您的回答!我通过 nextjs 链接标签切换基本的 html 锚标签来解决它。但我会使用你的代码,它更干净,至少 imo :) 祝你有美好的一天
  • 另外 - 它会让您更接近常见的用例(因为这是作为文档中的上下文完成的)。使用此设置,您应该更不容易出错。很高兴你能把它整理好!
猜你喜欢
  • 1970-01-01
  • 2020-10-25
  • 2021-07-22
  • 2021-06-12
  • 1970-01-01
  • 2021-12-23
  • 2021-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多