authProvider 在安装 Dashboard 后完成其 Promise
authProvider is finishing its Promise after the Dashboard being mounted
使用 [react-admin]
我有一个自定义仪表板,用于验证参数并重定向到名为 pages
:
的页面
class DashBoard extends Component {
componentDidMount() {
const { push } = this.props;
if (!localStorage.getItem("activePage")) {
push("/pages");
}
...
我还有这个从后端获取身份验证数据的 authProvider:
export default (type, params) => {
if (type === AUTH_LOGIN) {
const { authResponse } = params;
const request = new Request('https://localhost:8080/users/auth', {
method: 'POST',
body: JSON.stringify({ userID }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.body);
}
return response.json();
}).then(({ user }) => {
localStorage.setItem('token', user.token);
localStorage.setItem('name', user.name);
localStorage.setItem('email', user.email);
localStorage.setItem('activePage', user.activePage);
}).catch((err) => {
return Promise.reject(err);
}).finally(() => {
return Promise.resolve();});
...
我精简了代码以仅显示 Promises 部分。
然而,代码的最后一部分 finally
在 “/pages”
挂载之后执行,正如我在 console.log 中看到的那样。而且,在 “/pages”
我检查后端返回的 activePage,发生了什么太晚了。
authProvider 中缺少什么来“等待”promise 完成?
四处挖掘我发现了这个 并对我的代码进行了一些更改。现在它工作正常:
默认函数是async
,调用一个auth
函数,最后returns一个Promise。
// in src/authProvider.js
export default async (type, params) => {
if (type === AUTH_LOGIN) {
const { authResponse } = params;
const user = await auth(userID);
localStorage.setItem('token', user.token);
if (user.activePage) localStorage.setItem('activePage', user.activePage);
return Promise.resolve();
auth
函数returns一个Promise:
const auth = async (userID) => {
const request = new Request('https://localhost:8080/users/auth', {
method: 'POST',
body: JSON.stringify({ userID }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.body);
}
return response.json();
})
.then(({ user }) => {
return user;
});
}
尝试使用 async/await
,遵循流程会更容易一些:
export default async (type, userID) => {
if (type === AUTH_LOGIN) {
try {
const res = await fetch('https://localhost:8080/users/auth', {
method: 'POST',
body: JSON.stringify({ userID })
headers: new Headers({ 'Content-Type': 'application/json' }),
}) // fetch API data
const { user: { token, name, email, activePage } } = await res.json(); // convert to JSON, from the JSON's user prop, pull out token, name, email, activePage
localStorage.setItem('token', token);
localStorage.setItem('name', name);
localStorage.setItem('email', email);
localStorage.setItem('activePage', activePage);
} catch(err) { console.error(err); }
}
}
使用 [react-admin]
我有一个自定义仪表板,用于验证参数并重定向到名为 pages
:
class DashBoard extends Component {
componentDidMount() {
const { push } = this.props;
if (!localStorage.getItem("activePage")) {
push("/pages");
}
...
我还有这个从后端获取身份验证数据的 authProvider:
export default (type, params) => {
if (type === AUTH_LOGIN) {
const { authResponse } = params;
const request = new Request('https://localhost:8080/users/auth', {
method: 'POST',
body: JSON.stringify({ userID }),
headers: new Headers({ 'Content-Type': 'application/json' }),
});
fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.body);
}
return response.json();
}).then(({ user }) => {
localStorage.setItem('token', user.token);
localStorage.setItem('name', user.name);
localStorage.setItem('email', user.email);
localStorage.setItem('activePage', user.activePage);
}).catch((err) => {
return Promise.reject(err);
}).finally(() => {
return Promise.resolve();});
...
我精简了代码以仅显示 Promises 部分。
然而,代码的最后一部分 finally
在 “/pages”
挂载之后执行,正如我在 console.log 中看到的那样。而且,在 “/pages”
我检查后端返回的 activePage,发生了什么太晚了。
authProvider 中缺少什么来“等待”promise 完成?
四处挖掘我发现了这个
默认函数是
async
,调用一个auth
函数,最后returns一个Promise。// in src/authProvider.js export default async (type, params) => { if (type === AUTH_LOGIN) { const { authResponse } = params; const user = await auth(userID); localStorage.setItem('token', user.token); if (user.activePage) localStorage.setItem('activePage', user.activePage); return Promise.resolve();
auth
函数returns一个Promise:const auth = async (userID) => { const request = new Request('https://localhost:8080/users/auth', { method: 'POST', body: JSON.stringify({ userID }), headers: new Headers({ 'Content-Type': 'application/json' }), }); return fetch(request) .then(response => { if (response.status < 200 || response.status >= 300) { throw new Error(response.body); } return response.json(); }) .then(({ user }) => { return user; }); }
尝试使用 async/await
,遵循流程会更容易一些:
export default async (type, userID) => {
if (type === AUTH_LOGIN) {
try {
const res = await fetch('https://localhost:8080/users/auth', {
method: 'POST',
body: JSON.stringify({ userID })
headers: new Headers({ 'Content-Type': 'application/json' }),
}) // fetch API data
const { user: { token, name, email, activePage } } = await res.json(); // convert to JSON, from the JSON's user prop, pull out token, name, email, activePage
localStorage.setItem('token', token);
localStorage.setItem('name', name);
localStorage.setItem('email', email);
localStorage.setItem('activePage', activePage);
} catch(err) { console.error(err); }
}
}