#javascript #reactjs #react-hooks
#javascript #reactjs #реагирующие хуки
Вопрос:
Привет, ребята, итак, я работаю над приложением React и использую React-хуки. Я создал новый контекст с помощью creatContext, который содержит идентификатор пользователя и токен. Я настраиваю навигационную панель на изменение при регистрации пользователя, а также устанавливаю перенаправление со страницы авторизации на другую страницу при регистрации пользователя. Проблема в том, что когда я выполняю вход в систему, панель навигации фактически меняется, но она не перенаправляет меня туда, где она должна быть, даже если я вошел в систему. Почему он не обновляет страницу авторизации? Я также пытался использовать
Файл, в котором я создаю контекст :
import React ,{ createContext} from 'react' ;
const context= createContext({
userId:null,
token: null ,
login: (userId, token , tokenExpiration)=> {} ,
logout: ()=>{}
});
export default context ;
App.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 amp;amp; <Redirect from="/auth" to="/bookings" exact /> }
{context.token amp;amp; <Redirect from="/auth" to="/events" exact /> }
{!context.token amp;amp; <Redirect from="/" to="/auth" exact />}
{!context.token amp;amp; <Redirect from="/bookings" to="/auth" exact />}
{!context.token amp;amp; <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 amp;amp; 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>
}
компонент панели навигации:
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 amp;amp;
<li>
<NavLink to="/auth"> Authenticate</NavLink>
</li>
}
<li>
<NavLink to="/events"> Events</NavLink>
</li>
{ context.token amp;amp;
<li>
<NavLink to="/bookings"> Bookings</NavLink>
</li>
}
</ul>
</nav>
</header>
)
}
Ответ №1:
вы не можете использовать что-либо context
внутри component
того, что вы инициализируете context
в
для вашего случая здесь вы должны создать другой component
, например router
, и использовать context
inside и инициализировать контекст в App
компоненте
Layout.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 amp;amp; <Redirect from="/auth" to="/bookings" exact /> }
{context.token amp;amp; <Redirect from="/auth" to="/events" exact /> }
{!context.token amp;amp; <Redirect from="/" to="/auth" exact />}
{!context.token amp;amp; <Redirect from="/bookings" to="/auth" exact />}
{!context.token amp;amp; <Route path="/auth" component={AuthPage} />}
<Route path="/events" component={EventsPage} />
{ <Route path="/bookings" component={BookingsPage} />}
</Switch>
</main>
</BrowserRouter>
);
}
export default Layout;
App.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;
Комментарии:
1. Спасибо. Я переместил код в Layout.js но сохранил методы входа в систему, выхода из системы, обновления и обновления на App.js досье . Теперь это работает, спасибо.