Javascript React上下文API可能存在异步/等待问题?

Javascript 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

我的目标是将无效令牌设置为全局状态,因此如果jwt令牌有效,我可以呈现销售页面;如果没有,则将用户重定向到登录页面。但是,isValidToken函数返回undefined,这可能是因为它不是异步函数。但是,如果我将其设置为异步函数,则会出现错误。还有,有没有更好、更简洁的方法来实现目标

此代码返回未定义的

index.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
};
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。谢谢!:)