我对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.)
我唯一想要实现的是加载' client_id'和'域名'变量通过API调用,在其他所有加载之前。所以基本上是这样的:
# 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调用设置一些常量变量。这不可能,但我似乎无法找到一个好的解决方案。
答案 0 :(得分:1)
我是React的新手,所以也许你可以等待其他人的确认。
您通过获取获取信息并将其分配给某些变量,但正常流程并不知道那时您所解释的那些变量(或新值)。所以,你可以在这里使用状态。作为一个新的React开发人员,我从一些默认状态开始,在componentDidMount中,我执行Ajax并在那里更改状态(setState)。因此,自状态发生变化后,您的组件将再次被重新渲染。
答案 1 :(得分:0)
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>
)
}
}
答案 2 :(得分:0)
这是一个典型的异步情况,如果您认为所有组件都依赖于fetch()
函数调用的输出,则必须在.then()
下列出所有组件,例如fetch(url).then( all of your code here)
}。
话虽如此,如果你需要根据fetch返回的内容渲染一些组件,你可以在setState({})
中使用.then()
并相应地在render()
方法中调用这些组件