【问题标题】:React redirect asyc and await doesn't wait反应重定向异步和等待不等待
【发布时间】:2019-01-14 04:42:30
【问题描述】:

我有以下代码,我想从 url 获取访问令牌并将其放入会话存储中,并让我的子组件使用访问令牌来获取我的信息。但是,当组件第一次加载时,它似乎没有找到访问令牌,但如果我再次刷新它就可以工作。为了解决这个问题,我想到了使用 async / await 以便在未设置会话令牌之前它不会进一步重定向到子组件,但这似乎并没有等待设置令牌。不知道我做错了什么?

class App extends React.Component {
constructor(props){
    super(props);
    this.processToken();
}

componentDidMount() {
   const { user } = this.props; 
   const { accessToken } = user;
   // expecting access token to print here by it is not
   console.log('user token : ', accessToken);
}
 processToken = async () => {
try {
    const params = querySearch(this.props.location.search);
    if('accessToken' in params){
       await new Promise((resolve,reject) => {
          this.setOrderContext(params);
           resolve();
       } );  
        this.props.history.push(`/myinfo`);
    }
} catch(ex) {
  console.log(ex);
}

}

   setOrderContext (params){
     //this action calls a reducer and put the token in session storage
     this.props.userActions.processUserToken({data: {accessToken:params.accessToken}});

}

render() {
    return (

        <Switch>
            //myinfo component needs accessToken to retrieve my info
            <Route path="/myInfo" component={InofUI.App} />
        </Switch>

    );
}

【问题讨论】:

    标签: reactjs promise async-await


    【解决方案1】:

    问题在于你的构造函数中调用this.processToken()。由于您没有也不能等待这个调用,React 只是调用该方法并继续其生命周期。 因此,componentDidMount 可能在您的 setOrderContext 完成之前被调用。

    在 React 环境中,您应该像往常一样在 componentDidMount 中获取资源并进行异步调用。这可确保您的组件在访问任何外部资源之前顺利且正确地呈现。

    您要做的是将this.processToken() 调用从构造函数移至componentDidMount 方法,并确保它在那里得到正确处理。

    【讨论】:

      【解决方案2】:

      这对我有用。

      class App extends React.Component {
      
      componentDidMount() {
         this.processToken();
      
      }
       processToken = () => {
          try {
              const params = querySearch(this.props.location.search);
              if('accessToken' in params){
                  this.setOrderContext(params);
                  this.props.history.push(`/myinfo`);
              }
          } catch(ex) {
            console.log(ex);
          }
          }
      
         setOrderContext (params){
           //this action calls a reducer and put the token in session storage
           this.props.userActions.processUserToken({data: {accessToken:params.accessToken}});
      }
      
      render() {
          return (
      
              <Switch>
                  //myinfo component needs accessToken to retrieve my info
                  <Route path="/myInfo" component={InofUI.App} />
              </Switch>
      
          );
      } 
      

      然后在 InfoUI.App 中

      componentDidMount() {
              this.retrieveMyInfo();
          }
      
          retrieveMyInfo = async () => {
              await this.untilTokenIsSet();
              const { location, history } = this.props;
              this.props.processUser(location, history);
          }
      
          untilTokenIsSet= () => {
              const poll = (resolve) => {
                  const { user } = this.props;
                  const { accessToken } = user;
                  console.log('getting accessToken', accessToken);
                  if (accessToken) {
                      resolve();
                  } else {
                      console.log('wating for token .. ');
                      setTimeout(() => poll(resolve), 100);
                  }
              };
              return new Promise(poll);
          } 
      

      【讨论】:

        猜你喜欢
        • 2019-10-21
        • 2016-07-07
        • 2016-03-25
        • 2017-10-09
        • 2020-11-23
        • 1970-01-01
        • 2017-12-11
        相关资源
        最近更新 更多