[英]why useContext updated only in children components/functions?
Hi guys so I'm working on a React App and I'm using React-Hooks .大家好,我正在开发一个 React 应用程序,我正在使用 React-Hooks 。 I created a new context with by using creatContext that holds the userId and token .我使用包含 userId 和 token 的 creatContext 创建了一个新上下文。 I set the navbar to change when user is logged , and I also set the Redirect from the AuthPage to another page when user is logged.我将导航栏设置为在用户登录时更改,并且在用户登录时将重定向从 AuthPage 设置为另一个页面。 The problem is that when I do login , the navbar actually changes but it does no redirect me to where it should be , even though I logged in .问题是,当我登录时,导航栏实际上发生了变化,但它没有将我重定向到它应该在的位置,即使我已登录。 Why isn't it updating the AuthPage?为什么不更新 AuthPage? I also tried to use我也尝试使用
The file where I create the context :我创建上下文的文件:
import React ,{ createContext} from 'react' ;
const context= createContext({
userId:null,
token: null ,
login: (userId, token , tokenExpiration)=> {} ,
logout: ()=>{}
});
export default context ;
App.js:应用程序.js:
import './App.css';
import AuthPage from './pages/AuthPage'
import {BrowserRouter, Route , Redirect , Switch} from 'react-router-dom'
import EventsPage from './pages/EventsPage';
import BookingsPage from './pages/BookingsPage';
import MainNavigation from './components/Navigation/MainNavigation'
import AuthContext from './context/auth-context';
import { useState , useContext, useMemo } from 'react';
function App() {
const context = useContext(AuthContext);
const[token , setToken] =useState(null) ;
const[userId , setUserId] =useState(null);
const login=(token,userId , tokenExpiration)=>{
setToken(token) ;
setUserId(userId);
}
const logout=()=>{
setToken(null);
setUserId(null);
}
const updateAndRender =useMemo(() => ( {
token:token ,
userId:userId ,
login:login,
logout:logout
}
), [token , userId , login]);
return (
<BrowserRouter>
<AuthContext.Provider
value={updateAndRender}
>
<MainNavigation/>
<main className="main-content">
<Switch>
{context.token && <Redirect from="/auth" to="/bookings" exact /> }
{context.token && <Redirect from="/auth" to="/events" exact /> }
{!context.token && <Redirect from="/" to="/auth" exact />}
{!context.token && <Redirect from="/bookings" to="/auth" exact />}
{!context.token && <Route path="/auth" component={AuthPage} />}
<Route path="/events" component={EventsPage} />
{ <Route path="/bookings" component={BookingsPage} />}
</Switch>
</main>
</AuthContext.Provider>
</BrowserRouter>
);
}
export default App;
AuthPage:身份验证页面:
import React , {useContext, useState , useEffect} from 'react';
import './AuthPage.css';
import AuthContext from '../context/auth-context';
export default function Authpage(props) {
const [email , setEmail]=useState(" ");
const [password , setPassword]=useState(" ");
const [isLogin , setIsLogin]=useState(true);
const context = useContext(AuthContext);
const swithmodeHandler=()=> { setIsLogin(!isLogin)}
const submitHandler=async (e)=>{
e.preventDefault();
let requestBody ={
query:
`
query{
login(email:"${email}" , password:"${password}")
{
userId
token
tokenExpiration
}
}
`
}
if(isLogin){
requestBody={
query:`
mutation{
createUser(userInput:{email:"${email}" , password:"${password}" })
{
_id
email
}
}`
}
}
try {
const requestToGql = await fetch('http://localhost:3001/graphql' , {
method:'POST' ,
body:JSON.stringify(requestBody) ,
headers:{
'Content-Type': 'application/json'
}})
if(requestToGql.status!==200 && requestToGql.status!==201){
throw new Error("Failed creating user");
}
const resData=await requestToGql.json() ;
if((Object.keys(resData.data.login) !==0) || resData.data.login.token){
context.login(resData.data.login.userId,
resData.data.login.token,
resData.data.login.tokenExpiration
) ;
}
return resData ;
} catch (error) {
console.log(error)
}
}
return <form className="auth-form" onSubmit={submitHandler}>
<div className="form-control"> <label htmlFor="email"> Email</label>
<input value={email} type="email" id="email" onChange={e=>setEmail(e.target.value)}/>
</div>
<div className="form-control">
<label htmlFor="password"> Password</label>
<input value={password} type="password" id="password" onChange={e=>setPassword(e.target.value)}/>
</div>
<div className="form-actions">
<button type="submit"> Submit</button>
<button onClick={swithmodeHandler} type="button"> {isLogin? "Signup" : "Login"}</button>
</div>
</form>
}
the navbar component:导航栏组件:
import React , {useContext} from 'react' ;
import {NavLink} from 'react-router-dom'
import './MainNavigation.css'
import AuthContext from '../../context/auth-context'
export default function MainNavigation(props){
const context = useContext(AuthContext) ;
return(
<header className="main-navigation">
<div className="main-navigation_logo">
<h1> Yul's Gym</h1>
</div>
<nav className="main-navigation_items">
<ul>
{ !context.token &&
<li>
<NavLink to="/auth"> Authenticate</NavLink>
</li>
}
<li>
<NavLink to="/events"> Events</NavLink>
</li>
{ context.token &&
<li>
<NavLink to="/bookings"> Bookings</NavLink>
</li>
}
</ul>
</nav>
</header>
)
}
you can't use any context
inside the component
that you initialize the context
in您不能在初始化context
的component
内使用任何context
for your case here you should create another component
for example router
and use the context
inside and initialize the context in the App
component对于您的情况,您应该创建另一个component
,例如router
并使用内部的context
并初始化App
组件中的上下文
Layout.js布局.js
import AuthPage from './pages/AuthPage'
import {BrowserRouter, Route , Redirect , Switch} from 'react-router-dom'
import EventsPage from './pages/EventsPage';
import BookingsPage from './pages/BookingsPage';
import MainNavigation from './components/Navigation/MainNavigation'
import AuthContext from './context/auth-context';
import { useState , useContext, useMemo } from 'react';
function Layout() {
const context = useContext(AuthContext);
const[token , setToken] =useState(null) ;
const[userId , setUserId] =useState(null);
const login=(token,userId , tokenExpiration)=>{
setToken(token) ;
setUserId(userId);
}
const logout=()=>{
setToken(null);
setUserId(null);
}
const updateAndRender =useMemo(() => ( {
token:token ,
userId:userId ,
login:login,
logout:logout
}
), [token , userId , login]);
return (
<BrowserRouter>
<MainNavigation/>
<main className="main-content">
<Switch>
{context.token && <Redirect from="/auth" to="/bookings" exact /> }
{context.token && <Redirect from="/auth" to="/events" exact /> }
{!context.token && <Redirect from="/" to="/auth" exact />}
{!context.token && <Redirect from="/bookings" to="/auth" exact />}
{!context.token && <Route path="/auth" component={AuthPage} />}
<Route path="/events" component={EventsPage} />
{ <Route path="/bookings" component={BookingsPage} />}
</Switch>
</main>
</BrowserRouter>
);
}
export default Layout;
App.js应用程序.js
import './App.css';
import Layout from '../Layout/Layout.js'
import AuthContext from './context/auth-context';
function App() {
return (
<AuthContext.Provider
value={updateAndRender}
>
<Layout />
</AuthContext.Provider>
);
}
export default App;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.