实现效果:
- 异步组件要实现的功能,异步请求数据,请求完数据再挂载组件。没有加载完数据显示 loading 效果。
- 可量化生产。
主要思路:
- 可以使用 React.lazy 实现动态加载,那么可以先请求数据,然后再加载组件,这时候以 props 形式将数据传递给目标组件,实现异步效果。
/**
*
* @param {*} Component 需要异步数据的component
* @param {*} api 请求数据接口,返回Promise,可以再then中获取与后端交互的数据
* @returns
*/
function AysncComponent(Component,api){
const AysncComponentPromise = () => new Promise(async (resolve)=>{
const data = await api()
resolve({
default: (props) => <Component rdata={data} { ...props} />
})
})
return React.lazy(AysncComponentPromise)
}
思路:
- 用 AysncComponent 作为一个 HOC 包装组件,接受两个参数,第一个参数为当前组件,第二个参数为请求数据的 api 。
- 声明一个函数给 React.lazy 作为回调函数,React.lazy 要求这个函数必须是返回一个 Promise 。在 Promise 里面通过调用 api 请求数据,然后根据返回来的数据 rdata 渲染组件,别忘了接受并传递 props 。
使用:
/* 数据模拟 */
const getData = () => {
return new Promise((resolve) => {
//模拟异步
setTimeout(() => {
resolve({
name: "alien",
say: "let us learn React!",
});
}, 1000);
});
};
/* 测试异步组件 */
function Test({ rdata, age }) {
const { name, say } = rdata;
console.log("组件渲染");
return (
<div>
<div> hello , my name is {name} </div>
<div>age : {age} </div>
<div> i want to say {say} </div>
</div>
);
}
/* 父组件 */
export default class Index extends React.Component {
LazyTest = AysncComponent(
Test,
getData
); /* 需要每一次在组件内部声明,保证每次父组件挂载,都会重新请求数据 ,防止内存泄漏。 */
render() {
const { LazyTest } = this;
return (
<div>
<Suspense fallback={<div>loading...</div>}>
<LazyTest age={18} />
</Suspense>
</div>
);
}
}
效果:
- 如上 name 和 say 都是数据交互获取的数据。
- 组件只渲染了一次,实现了异步渲染的效果