Javascript React上下文API可能存在异步/等待问题?
我的目标是将无效令牌设置为全局状态,因此如果jwt令牌有效,我可以呈现销售页面;如果没有,则将用户重定向到登录页面。但是,isValidToken函数返回undefined,这可能是因为它不是异步函数。但是,如果我将其设置为异步函数,则会出现错误。还有,有没有更好、更简洁的方法来实现目标 此代码返回未定义的 index.jsJavascript React上下文API可能存在异步/等待问题?,javascript,reactjs,react-hooks,react-context,Javascript,Reactjs,React Hooks,React Context,我的目标是将无效令牌设置为全局状态,因此如果jwt令牌有效,我可以呈现销售页面;如果没有,则将用户重定向到登录页面。但是,isValidToken函数返回undefined,这可能是因为它不是异步函数。但是,如果我将其设置为异步函数,则会出现错误。还有,有没有更好、更简洁的方法来实现目标 此代码返回未定义的 index.js import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import Ap
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter as Router, Route, Link} from 'react-router-dom'
import { PrivateRoute } from './auth';
//includes
// Bootstrap core CSS
import 'bootstrap/dist/css/bootstrap.min.css';
//custom css for the page.
import './assets/css/style.css'
// custom fonts for the page.
//import * as Pages from './components';
//components
import Header from './components/headerComponent/header'
import Footer from './components/footerComponent/footer'
import {Homepage, SignIn, SignUp, Dashboard, Sell} from './components/pages'
import {UsersContextProvider} from './contexts'
ReactDOM.render(
<Router>
<div className="App">
<UsersContextProvider>
<Header />
<div className="content">
<Route exact path='/' component={Homepage} />
<PrivateRoute exact path = '/dashboard' component={Dashboard} />
<Route exact path='/signin' component={SignIn} />
<Route exact path='/signup' component={SignUp} />
<Route exact path='/sell' component={Sell} />
</div>
<Footer />
</UsersContextProvider>
</div>
</Router>,
document.getElementById('root'));
import React, { Component, useContext } from 'react';
import { Redirect } from "react-router-dom";
import '../../assets/css/sell.css';
// import {isLoggedIn} from '../../auth';
import API from '../../api';
import { UsersContext } from "../../contexts";
const Sell = (props) => {
//get the usersContext
const { isUserSignedIn, isValidToken, checkToken } = useContext(UsersContext);
return (
<div>
{checkToken()}
{console.log(checkToken())}
{console.log(isUserSignedIn)}
{console.log(isValidToken)}
<h4>User Details: {isUserSignedIn}</h4>
</div>)
}
export default Sell;
export function isValidToken () {
let token = localStorage.getItem("jwt_token");
if(token == null){
return false
} else{
API.get('/users/user_detail', {
headers: {
'Authorization': `Bearer ${token}`
}
}).then(res => {
console.log("valid token");
return res
}).catch(err => {
return false
})
}
}
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = () => {
setIsValidToken(isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};`
// import React, { Component } from 'react';
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = async () => {
setIsValidToken(await isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};
context.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter as Router, Route, Link} from 'react-router-dom'
import { PrivateRoute } from './auth';
//includes
// Bootstrap core CSS
import 'bootstrap/dist/css/bootstrap.min.css';
//custom css for the page.
import './assets/css/style.css'
// custom fonts for the page.
//import * as Pages from './components';
//components
import Header from './components/headerComponent/header'
import Footer from './components/footerComponent/footer'
import {Homepage, SignIn, SignUp, Dashboard, Sell} from './components/pages'
import {UsersContextProvider} from './contexts'
ReactDOM.render(
<Router>
<div className="App">
<UsersContextProvider>
<Header />
<div className="content">
<Route exact path='/' component={Homepage} />
<PrivateRoute exact path = '/dashboard' component={Dashboard} />
<Route exact path='/signin' component={SignIn} />
<Route exact path='/signup' component={SignUp} />
<Route exact path='/sell' component={Sell} />
</div>
<Footer />
</UsersContextProvider>
</div>
</Router>,
document.getElementById('root'));
import React, { Component, useContext } from 'react';
import { Redirect } from "react-router-dom";
import '../../assets/css/sell.css';
// import {isLoggedIn} from '../../auth';
import API from '../../api';
import { UsersContext } from "../../contexts";
const Sell = (props) => {
//get the usersContext
const { isUserSignedIn, isValidToken, checkToken } = useContext(UsersContext);
return (
<div>
{checkToken()}
{console.log(checkToken())}
{console.log(isUserSignedIn)}
{console.log(isValidToken)}
<h4>User Details: {isUserSignedIn}</h4>
</div>)
}
export default Sell;
export function isValidToken () {
let token = localStorage.getItem("jwt_token");
if(token == null){
return false
} else{
API.get('/users/user_detail', {
headers: {
'Authorization': `Bearer ${token}`
}
}).then(res => {
console.log("valid token");
return res
}).catch(err => {
return false
})
}
}
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = () => {
setIsValidToken(isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};`
// import React, { Component } from 'react';
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = async () => {
setIsValidToken(await isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};
//从“/auth”导入{isValidToken};
////用户上下文
//const UserContext=React.createContext();
//导出默认类UserProvider扩展组件{
//状态={
//伊斯洛格丁:错,
//isValidToken:错误
// }
//render(){
//返回(
//
//{this.props.children}
//
// )
// }
// }
从“React”导入React,{createContext,useState};
从“../auth”导入{isValidToken as isValidTokenFunc};
从“道具类型”导入道具类型;
export const Context=createContext({});
导出常量提供程序=props=>{
//初始值从道具中获得
常数{
isUserSignedIn:initialIsUserSignedIn,
isValidToken:初始值isValidToken,
儿童
}=道具;
//使用State保存这些值
const[isUserSignedIn,setIsUserSignedIn]=useState(initialIsUserSignedIn);
const[isValidToken,setIsValidToken]=useState(initialIsValidToken);
const checkToken=()=>{
setIsValidToken(isValidTokenFunc())
}
//使上下文对象:
常量usersContext={
isUserSignedIn,
setIsUserSignedIn,
是有效的吗,
设定为有效状态,
支票代币
};
//在提供程序中传递值并返回
返回{children};
};
导出常量{Consumer}=Context;
Provider.propTypes={
用户:PropTypes.bool,
selectedUser:PropTypes.bool
};
Provider.defaultProps={
isUserSignedIn:false,
isValidToken:错误
};`
此代码返回错误,试图使isValidToken异步
contexts.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { BrowserRouter as Router, Route, Link} from 'react-router-dom'
import { PrivateRoute } from './auth';
//includes
// Bootstrap core CSS
import 'bootstrap/dist/css/bootstrap.min.css';
//custom css for the page.
import './assets/css/style.css'
// custom fonts for the page.
//import * as Pages from './components';
//components
import Header from './components/headerComponent/header'
import Footer from './components/footerComponent/footer'
import {Homepage, SignIn, SignUp, Dashboard, Sell} from './components/pages'
import {UsersContextProvider} from './contexts'
ReactDOM.render(
<Router>
<div className="App">
<UsersContextProvider>
<Header />
<div className="content">
<Route exact path='/' component={Homepage} />
<PrivateRoute exact path = '/dashboard' component={Dashboard} />
<Route exact path='/signin' component={SignIn} />
<Route exact path='/signup' component={SignUp} />
<Route exact path='/sell' component={Sell} />
</div>
<Footer />
</UsersContextProvider>
</div>
</Router>,
document.getElementById('root'));
import React, { Component, useContext } from 'react';
import { Redirect } from "react-router-dom";
import '../../assets/css/sell.css';
// import {isLoggedIn} from '../../auth';
import API from '../../api';
import { UsersContext } from "../../contexts";
const Sell = (props) => {
//get the usersContext
const { isUserSignedIn, isValidToken, checkToken } = useContext(UsersContext);
return (
<div>
{checkToken()}
{console.log(checkToken())}
{console.log(isUserSignedIn)}
{console.log(isValidToken)}
<h4>User Details: {isUserSignedIn}</h4>
</div>)
}
export default Sell;
export function isValidToken () {
let token = localStorage.getItem("jwt_token");
if(token == null){
return false
} else{
API.get('/users/user_detail', {
headers: {
'Authorization': `Bearer ${token}`
}
}).then(res => {
console.log("valid token");
return res
}).catch(err => {
return false
})
}
}
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = () => {
setIsValidToken(isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};`
// import React, { Component } from 'react';
// import {isValidToken} from './auth';
// // User context
// const UserContext = React.createContext();
// export default class UserProvider extends Component {
// state = {
// isLoggedIn : false,
// isValidToken : false
// }
// render() {
// return (
// <UserContext.Provider value={{
// state: this.state,
// isValidToken: isValidToken
// }}>
// {this.props.children}
// </UserContext.Provider>
// )
// }
// }
import React, { createContext, useState } from "react";
import { isValidToken as isValidTokenFunc }from '../auth';
import PropTypes from "prop-types";
export const Context = createContext({});
export const Provider = props => {
// Initial values are obtained from the props
const {
isUserSignedIn: initialIsUserSignedIn,
isValidToken: initialIsValidToken,
children
} = props;
// Use State to keep the values
const [isUserSignedIn, setIsUserSignedIn] = useState(initialIsUserSignedIn);
const [isValidToken, setIsValidToken] = useState(initialIsValidToken);
const checkToken = async () => {
setIsValidToken(await isValidTokenFunc())
}
// Make the context object:
const usersContext = {
isUserSignedIn,
setIsUserSignedIn,
isValidToken,
setIsValidToken,
checkToken
};
// pass the value in provider and return
return <Context.Provider value={usersContext}>{children}</Context.Provider>;
};
export const { Consumer } = Context;
Provider.propTypes = {
users: PropTypes.bool,
selectedUser: PropTypes.bool
};
Provider.defaultProps = {
isUserSignedIn: false,
isValidToken: false
};
//从'React'导入React,{Component};
//从“/auth”导入{isValidToken};
////用户上下文
//const UserContext=React.createContext();
//导出默认类UserProvider扩展组件{
//状态={
//伊斯洛格丁:错,
//isValidToken:错误
// }
//render(){
//返回(
//
//{this.props.children}
//
// )
// }
// }
从“React”导入React,{createContext,useState};
从“../auth”导入{isValidToken as isValidTokenFunc};
从“道具类型”导入道具类型;
export const Context=createContext({});
导出常量提供程序=props=>{
//初始值从道具中获得
常数{
isUserSignedIn:initialIsUserSignedIn,
isValidToken:初始值isValidToken,
儿童
}=道具;
//使用State保存这些值
const[isUserSignedIn,setIsUserSignedIn]=useState(initialIsUserSignedIn);
const[isValidToken,setIsValidToken]=useState(initialIsValidToken);
const checkToken=async()=>{
setIsValidToken(等待isValidTokenFunc())
}
//使上下文对象:
常量usersContext={
isUserSignedIn,
setIsUserSignedIn,
是有效的吗,
设定为有效状态,
支票代币
};
//在提供程序中传递值并返回
返回{children};
};
导出常量{Consumer}=Context;
Provider.propTypes={
用户:PropTypes.bool,
selectedUser:PropTypes.bool
};
Provider.defaultProps={
isUserSignedIn:false,
isValidToken:错误
};
这可能是
useffect
的一种情况:您没有从auth.js文件上的api调用返回结果,只需在Api之前添加return
。get
在Api之前添加return.get会导致程序崩溃,因为它会无限循环到你试图返回一堆函数的组件Sell
中。将它们移动到第一条评论中建议的效果中。嘿,Fedrico,这真的很有效。所以我将checkToken()移动到useffect()中,并在API.get()前面添加了return。谢谢!:)