[英]UseContext returns null in getServer side props NextJS
我在其他地方使用过上下文,例如登录、数据库功能等。 但是,当我尝试在自定义 api 或getServerSideProps
等位置的上下文中运行函数或变量时,它会返回以下错误TypeError: Cannot read properties of null (reading 'useContext')
。 我正在附加我的身份验证上下文、我的上下文初始化以及返回错误的getServerSideProps
函数
_app.js
import RootLayout from '../components/Layout'
import { AuthProvider } from '../configs/auth-context'
import '../styles/globals.css'
export default function App({ Component, pageProps }) {
return (
<AuthProvider >
<RootLayout>
<Component {...pageProps} />
</RootLayout>
</AuthProvider>
)}
授权上下文
import React, { useContext, useState, useEffect, useRef } from 'react'
import { auth, db, provider } from './firebase-config'
import { GoogleAuthProvider, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut, onAuthStateChanged, signInWithPopup } from 'firebase/auth'
import { doc, getDoc, setDoc } from 'firebase/firestore'
import {useRouter} from 'next/router';
const AuthContext = React.createContext({currentUser: {uid: "TestUid", email:"Testeremail@email.com"}})
export function UseAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const router = useRouter();
const [currentUser, setCurrentUser] = useState({uid: "TestUid", email:"Testeremail@email.com"})
const [loading, setLoading] = useState(true)
async function signup(email, password) {
createUserWithEmailAndPassword(auth, email, password)
.then(async (result) => {
const user = result.user;
await userToDb(user);
router.push('/portfolio');
return user;
}).catch((error) => {
console.error(error);
})
return
}
async function login(email, password) {
return signInWithEmailAndPassword(auth, email, password)
.then(async (result) => {
const user = result.user;
await userToDb(user);
router.push('/portfolio');
return user;
}).catch((error) => {
console.error(error)
})
}
function logout() {
router.push('/')
return signOut(auth)
}
async function googleSignIn() {
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then(async (result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential.accessToken;
// The signed-in user info.
const user = result.user;
await userToDb(user);
router.push('/portfolio');
return user
}).catch((error) => {
console.log(error)
// const errorCode = error.code;
// const errorMessage = error.message;
// The email of the user's account used.
// const email = error.customData.email;
// The AuthCredential type that was used.
// const credential = GoogleAuthProvider.credentialFromError(error);
} )
}
const userToDb = async (user) => {
// await setDoc(doc(db, "users", user.uid), {
// userEmail: user.email,
// userID: user.uid
// }, {merge: false})
let currentRef = doc(db, 'users', user.uid)
let currentUserID = user.uid;
let currentEmail = user.email;
await setDoc(currentRef, {
userEmail: currentEmail,
userID: currentUserID
}, {merge: false})
}
function fixData(docs) {
console.log("this works")
// setDocuments(docs);
let retMap = new Map();
if (currentUser !== null) {
docs?.map(function(doc) {
console.log(doc)
let tic = doc.stockTicker
let data = {
shares: doc.shares,
price: doc.price,
type: doc.type
}
if(!retMap.has(tic)) {
retMap.set(tic, [data]);
console.log(tic + " " + data)
// setMap(new Map(datamap.set(tic, {shares: shares, averagePrice: price})))
}
else {
let x = retMap.get(tic);
x.push(data);
}
})
console.log(retMap)
return retMap;
}
}
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, async user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
logout,
googleSignIn,
fixData
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
)
}
getServerSideProps
export async function getServerSideProps() {
let allDocs = []
let avgDocs = []
const {currentUser} = UseAuth()
return {
props: {allDocs, avgDocs}
}
}
不知道正确答案,但是hooks应该用在组件里,hooks无一例外地用在ssr上。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.