【问题标题】:React async loading of configuration variables反应配置变量的异步加载
【发布时间】:2017-10-16 04:26:30
【问题描述】:

我对 React 很陌生,我似乎无法解决一个简单的问题。我正在实现 auth0 锁定小部件,并将其导入到我的“routes.js”中,如下所示:

routes.js

import {requireAuth} from './js/helpers/AuthService.js';

我的 AuthService.js 没有构造函数,它只包含函数的声明,其中一些必须导出。片段:

AuthService.js

  const lock = new Auth0Lock(
  client_id,
  domain, {
    auth: {
      redirectUrl: `${window.location.origin}${LOGIN_ROUTE}`,
      responseType: 'token id_token',
        params: {
         scope: 'openid email' 
      },
    }
  }
);

const events = new EventEmitter();

lock.on('authenticated', authResult => {
  setAccessToken(authResult.accessToken);
  lock.getUserInfo(authResult.accessToken, (error, profile) => {
    if (error) { return setProfile({error}); }
    setProfile(profile);
    browserHistory.push(getNextPath());
    clearNextPath();
  });
});

export function login(options) {
  lock.show(options);

  return {
    hide() {
      lock.hide();
    }
  }
}
(etc.)

我唯一想要实现的是在加载其他所有内容之前通过 API 调用加载“client_id”和“domain”变量。所以基本上是这样的:

# fetch the config variables
fetch(url)
    .then(function(response) {
    if (response.status >= 400) {
       throw new Error("Bad response from server");
    }
    return response.json();
  })
  .then(function(data) {
     const client_id = data.client_id
     const domain = data.domain
  });

  # Proceed with normal flow
  const lock = new Auth0Lock(
  client_id,
  domain, {
    auth: {
      redirectUrl: `${window.location.origin}${LOGIN_ROUTE}`,
      responseType: 'token id_token',
        params: {
         scope: 'openid email' 
      },
    }
  }
);

我遇到的问题是 fetch 是一个异步调用,因此其他代码不会等待它完成,这会在其余代码中触发错误(client_id 和 domain 未定义)。

我读过componentDidMount函数,但总是提到它可以用来延迟渲染。我没有什么要渲染的,我只想声明一些函数。为此,我只需要基于 API 调用设置一些常量变量。这不可能,但我似乎找不到一个好的解决方案。

【问题讨论】:

    标签: reactjs react-native auth0


    【解决方案1】:

    这是一个典型的异步案例,如果你觉得你的所有组件都依赖于fetch()函数调用的输出,你必须把它全部列在.then()下面,比如fetch(url).then( all of your code here)

    话虽如此,如果您需要根据 fetch 返回的内容渲染某些组件,您可以在 .then() 中使用 setState({}) 并相应地在 render() 方法中调用这些组件。

    【讨论】:

      【解决方案2】:

      您可以在 react-async-wrapper 的帮助下在加载您的应用程序之前调用您的异步工作器

      import React from 'react';
      import { AsyncComponent } from 'react-async-wrapper';
      
      export default class AsyncApp extend React.Component {
          render() {
              return (
                  <AsyncComponent asyncProps={{
                      lock: () => fetch(url)
                              .then(function(response) {
                                  if (response.status >= 400) {
                                      throw new Error("Bad response from server");
                                  }
                                  return response.json();
                              })
                              .then(data => ({
                                  new Auth0Lock(
                                      data.client_id,
                                      data.domain,
                                      {
                                          auth: {
                                              redirectUrl: `${window.location.origin}${LOGIN_ROUTE}`,
                                              responseType: 'token id_token',
                                              params: {
                                                  scope: 'openid email' 
                                              },
                                          }
                                      }
                                  )
                              });
                  }}>
                      <App/> //now in App, you can accept lock by this.props.lock
                  </AsyncComponent>
              )
          }
      }
      

      【讨论】:

        【解决方案3】:

        我对 React 很陌生,所以也许你可以等待其他人的确认。

        您正在通过 fetch 获取信息并将它们分配给一些变量,但您的正常流程当时并不知道这些变量(或新值),正如您所解释的那样。所以,你可以在这里使用状态。作为一名新的 React 开发人员,我从一些默认状态开始,在 componentDidMount 中我做我的 Ajax 工作并在那里更改状态 (setState)。因此,由于状态更改,您的组件将再次重新渲染。

        【讨论】:

        • 这意味着我必须将我的函数放在从 Component 扩展的类中,对吧?但那我怎么还能导出这些函数呢?
        • 我不了解您的设计,但您可以使用标准导出方法(module.exports 或使用 ES6 导出)轻松导出组件(甚至是纯函数)。您的主要组件保存状态,这些状态将处理您的变量或您想要的任何内容,您将在 componentDidMount 等合适的地方执行 Ajax 内容。但正如我所说,我不知道你的设计,什么会触发状态?如果你不渲染任何东西(并且你的示例中没有任何 React 代码)也许你应该专注于 JS 本身。 ES7 中的 Promise 甚至异步函数(太新了)。正如我所说,我是新手 :)
        猜你喜欢
        • 2023-04-07
        • 2019-02-01
        • 2019-08-19
        • 2012-03-18
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-05
        相关资源
        最近更新 更多