在 nextjs 中使用 useContext 将令牌粘贴到 useReducer 中并获得未定义
paste token in useReducer with useContext in nextjs and get undefined
我在 Next.js 中使用 useReducer
和 useContext
时遇到问题。我想使用用户已经用 useReducer
和 useContext
创建的令牌,但是当我尝试时它是未定义的。我不知道该怎么办?
这是我的代码文件:
这是我的 AuthToken.js
文件:
import React, { createContext, useEffect, useReducer } from 'react';
// Create context
export const AuthToken = createContext();
const initialState = {
auth: {},
user: []
};
const ACTIONS = {
AUTH: "AUTH",
ADD_USERS: "ADD_USERS"
};
const reducer = (stateAuth, action) => {
switch(action.type) {
case ACTIONS.AUTH:
return {
...stateAuth,
auth: action.payload
};
case ACTIONS.ADD_USERS:
return {
...stateAuth,
user: action.payload
};
default:
return stateAuth;
};
};
export function DataProvider({children}) {
const {stateAuth, dispatchAuth} = useReducer(reducer, initialState);
useEffect(() => {
const firstLogin = localStorage.getItem("firstLogin");
if (firstLogin === true) {
async (token) => {
const res = await fetch("http://localhost:3000/api/users/", {
method: "GET",
headers: {
"Authorization": token
}
});
await res.json().then(res => {
res.err ? localStorage.removeItem("firstLogin") : dispatchAuth({
type: ACTIONS.AUTH,
payload: {
token: res.accessToken,
user: res.user
}
});
});
};
};
}, []);
return (
<AuthToken.Provider value={{stateAuth, dispatchAuth}}>
{children}
</AuthToken.Provider>
);
};
此代码用于从 Next.js 中的 api 文件夹获取令牌(无论如何我正在使用 next-connect
):
import dbConnect from '../../../utils/dbConnect';
import User from '../../../model/User';
import handler from '../../../components/handler';
import { hash } from 'bcrypt';
import jwt from 'jsonwebtoken';
import { createAccessToken } from "../../../utils/generateToken";
dbConnect();
export default handler.get(async (req, res) => {
try {
const token = req.cookies.auth;
if (!token) return res.status(400).json({ message: "Please Login To Get Access" });
const result = jwt.verify(token, process.env.JWT_REFRESH_TOKEN);
if (!result) return res.status(400).json({ message: "Token Has Been Expired" });
const user = await User.findById(result.userId);
if (!user) return res.status(400).json({ message: "User Does Not Exist" });
const accessToken = createAccessToken({ id: user._id });
res.status(200).json({ accessToken, user: {
userId: user._id,
myUserName: user.nama,
myUserEmail: user.email
}});
} catch(err) {
res.status(500).json({ message: "Server Error", err: err.message });
};
})
这是我的 _app.js
:
import "../styles/globals.css";
import { DataProvider } from "../utils/AuthToken";
function MyApp({ Component, pageProps }) {
return (
<DataProvider>
<Component {...pageProps} />
</DataProvider>
);
};
export default MyApp
这是我的index.js
(我想在这里使用令牌):
import React, { useContext } from 'react';
import Head from 'next/head';
import { AuthToken } from "../utils/AuthToken";
function Home() {
const { stateAuth, dispatchAuth } = useContext(AuthToken);
console.log(stateAuth, dispatchAuth); // When i console log it i get undefined for both of them. That's my problem is.
return (
<React.Fragment>
<Head>
<title>Try useContext and useReducer</title>
<meta name="icon" href="/favicon.ico" />
</Head>
</React.Fragment>
);
};
export default Home;
这是我的问题:console.log
在浏览器上未定义。
useReducer
hook returns 一个元组,但您正在将其解构为一个对象。正确的语法如下:
const [stateAuth, dispatchAuth] = useReducer(reducer, initialState);
我在 Next.js 中使用 useReducer
和 useContext
时遇到问题。我想使用用户已经用 useReducer
和 useContext
创建的令牌,但是当我尝试时它是未定义的。我不知道该怎么办?
这是我的代码文件:
这是我的 AuthToken.js
文件:
import React, { createContext, useEffect, useReducer } from 'react';
// Create context
export const AuthToken = createContext();
const initialState = {
auth: {},
user: []
};
const ACTIONS = {
AUTH: "AUTH",
ADD_USERS: "ADD_USERS"
};
const reducer = (stateAuth, action) => {
switch(action.type) {
case ACTIONS.AUTH:
return {
...stateAuth,
auth: action.payload
};
case ACTIONS.ADD_USERS:
return {
...stateAuth,
user: action.payload
};
default:
return stateAuth;
};
};
export function DataProvider({children}) {
const {stateAuth, dispatchAuth} = useReducer(reducer, initialState);
useEffect(() => {
const firstLogin = localStorage.getItem("firstLogin");
if (firstLogin === true) {
async (token) => {
const res = await fetch("http://localhost:3000/api/users/", {
method: "GET",
headers: {
"Authorization": token
}
});
await res.json().then(res => {
res.err ? localStorage.removeItem("firstLogin") : dispatchAuth({
type: ACTIONS.AUTH,
payload: {
token: res.accessToken,
user: res.user
}
});
});
};
};
}, []);
return (
<AuthToken.Provider value={{stateAuth, dispatchAuth}}>
{children}
</AuthToken.Provider>
);
};
此代码用于从 Next.js 中的 api 文件夹获取令牌(无论如何我正在使用 next-connect
):
import dbConnect from '../../../utils/dbConnect';
import User from '../../../model/User';
import handler from '../../../components/handler';
import { hash } from 'bcrypt';
import jwt from 'jsonwebtoken';
import { createAccessToken } from "../../../utils/generateToken";
dbConnect();
export default handler.get(async (req, res) => {
try {
const token = req.cookies.auth;
if (!token) return res.status(400).json({ message: "Please Login To Get Access" });
const result = jwt.verify(token, process.env.JWT_REFRESH_TOKEN);
if (!result) return res.status(400).json({ message: "Token Has Been Expired" });
const user = await User.findById(result.userId);
if (!user) return res.status(400).json({ message: "User Does Not Exist" });
const accessToken = createAccessToken({ id: user._id });
res.status(200).json({ accessToken, user: {
userId: user._id,
myUserName: user.nama,
myUserEmail: user.email
}});
} catch(err) {
res.status(500).json({ message: "Server Error", err: err.message });
};
})
这是我的 _app.js
:
import "../styles/globals.css";
import { DataProvider } from "../utils/AuthToken";
function MyApp({ Component, pageProps }) {
return (
<DataProvider>
<Component {...pageProps} />
</DataProvider>
);
};
export default MyApp
这是我的index.js
(我想在这里使用令牌):
import React, { useContext } from 'react';
import Head from 'next/head';
import { AuthToken } from "../utils/AuthToken";
function Home() {
const { stateAuth, dispatchAuth } = useContext(AuthToken);
console.log(stateAuth, dispatchAuth); // When i console log it i get undefined for both of them. That's my problem is.
return (
<React.Fragment>
<Head>
<title>Try useContext and useReducer</title>
<meta name="icon" href="/favicon.ico" />
</Head>
</React.Fragment>
);
};
export default Home;
这是我的问题:console.log
在浏览器上未定义。
useReducer
hook returns 一个元组,但您正在将其解构为一个对象。正确的语法如下:
const [stateAuth, dispatchAuth] = useReducer(reducer, initialState);