我有一个函数,该函数在调用该函数时刷新组件的数据。目前,它一次仅适用于一个组件。但是我想一次刷新两个组件。这是我的刷新功能:
fetchDataByName = name => {
const { retrievedData } = this.state;
const { fetcher } = this.props;
const fetch = _.find(fetcher, { name });
if (typeof fetch === "undefined") {
throw new Error(`Fetch with ${name} cannot be found in fetcher`);
}
this.fetchData(fetch, (error, data) => {
retrievedData[name] = data;
this._isMounted && this.setState({ retrievedData });
});
};
我的函数被这样调用:
refresh("meetingTypes");
当它作为道具传递给我的组件时:
return (
<Component
{...retrievedData}
{...componentProps}
refresh={this.fetchDataByName}
/>
);
我尝试将多个组件名称作为这样的数组传递:
const args = ['meetingTypes', 'exampleMeetingTypes'];
refresh(args);
然后检查我的fetchDataByName
函数是否name
是一个数组,并循环遍历该数组以获取数据。但是随后该函数仍然彼此执行而不是同时执行。所以我的问题是:
实现此目标的最佳方法是什么? 函数立即执行,而不是先刷新meetingTypes 然后是exampleMeetingTypes?
我应该使用async/await
还是有更好的选择?
fetchData
函数:
fetchData = (fetch, callback) => {
const { componentProps } = this.props;
let { route, params = [] } = fetch;
let fetchData = true;
// if fetcher url contains params and the param can be found
// in the component props, they should be replaced.
_.each(params, param => {
if (componentProps[param]) {
route = route.replace(`:${param}`, componentProps[param]);
} else {
fetchData = false; // don't fetch data for this entry as the params are not given
}
});
if (fetchData) {
axios
.get(route)
.then(({ data }) => {
if (this.isMounted) {
callback(null, data);
}
})
.catch(error => {
if (error.response.status == 403) {
this._isMounted && this.setState({ errorCode: 403 });
setMessage({
text: "Unauthorized",
type: "error"
});
}
if (error.response.status == 401) {
this._isMounted && this.setState({ errorCode: 401 });
window.location.href = "/login";
}
if (error.response.status != 403) {
console.error("Your backend is failing.", error);
}
callback(error, null);
});
} else {
callback(null, null);
}
};
答案 0 :(得分:1)
我假设fetchData
异步工作(ajax或类似的)。要并行刷新数据的两个方面,只需进行两次调用而不是一次:
refresh("meetingTypes");
refresh("exampleMeetingTypes");
两个ajax调用或任何将并行运行的调用,每个调用都会在完成时更新组件。 但是:请参见下面的“旁注”,fetchDataByName
有问题。
如果要避免两次更新组件,则必须更新fetchDataByName
以接受多个名称或返回结果的承诺(或类似结果),而不是直接更新组件,因此,呼叫者可以进行多个呼叫,并等待两个结果,然后再进行更新。
旁注:fetchDataByName
的这一方面令人怀疑:
fetchDataByName = name => {
const { retrievedData } = this.state; // <=============================
const { fetcher } = this.props;
const fetch = _.find(fetcher, { name });
if (typeof fetch === "undefined") {
throw new Error(`Fetch with ${name} cannot be found in fetcher`);
}
this.fetchData(fetch, (error, data) => {
retrievedData[name] = data; // <=============================
this._isMounted && this.setState({ retrievedData });
});
};
有两个问题:
retrievedData
对象替换为很旧的对象。相反:
fetchDataByName = name => {
// *** No `retrievedData` here
const { fetcher } = this.props;
const fetch = _.find(fetcher, { name });
if (typeof fetch === "undefined") {
throw new Error(`Fetch with ${name} cannot be found in fetcher`);
}
this.fetchData(fetch, (error, data) => {
if (this._isMounted) { // ***
this.setState(({retrievedData}) => ( // ***
{ retrievedData: {...retrievedData, [name]: data} } // ***
); // ***
} // ***
});
};
这将消除对象随传播的就地突变,并通过使用retrievedData
的回调版本来使用setState
的最新版本。