1. 数据加载策略
- 分离数据加载逻辑:将每个 API 的数据加载逻辑封装在单独的函数中,便于管理和复用。例如,可以使用
async/await
或者 Promise
来处理异步请求。
- 建立数据依赖关系图:分析各个组件所需数据之间的依赖关系,确定数据加载的先后顺序。
2. 结合 React 生命周期方法实现数据加载
componentDidMount
:在组件挂载后触发数据加载。如果数据有依赖关系,先加载依赖的数据,然后再根据依赖数据加载其他数据。例如:
import React, { Component } from 'react';
class MyComponent extends Component {
state = {
data1: null,
data2: null
};
async componentDidMount() {
try {
const response1 = await fetch('api-url-for-data1');
const data1 = await response1.json();
this.setState({ data1 });
const response2 = await fetch(`api-url-for-data2?param=${data1.someKey}`);
const data2 = await response2.json();
this.setState({ data2 });
} catch (error) {
console.error('Error loading data:', error);
}
}
render() {
const { data1, data2 } = this.state;
return (
<div>
{data1 && <p>Data1: {JSON.stringify(data1)}</p>}
{data2 && <p>Data2: {JSON.stringify(data2)}</p>}
</div>
);
}
}
componentDidUpdate
:如果组件的 props 或者 state 发生变化,可能需要重新加载数据。可以通过比较 prevProps 和 nextProps,或者 prevState 和 nextState 来决定是否需要重新加载。例如:
componentDidUpdate(prevProps, prevState) {
if (prevProps.someProp!== this.props.someProp) {
this.fetchNewData();
}
}
3. 数据缓存
- 内存缓存:在组件内部或者应用全局维护一个缓存对象。例如,可以在组件的静态属性中定义缓存,每次加载数据前先检查缓存中是否有对应的数据。
class MyComponent extends Component {
static cache = {};
async componentDidMount() {
if (MyComponent.cache['data1']) {
this.setState({ data1: MyComponent.cache['data1'] });
} else {
const response = await fetch('api-url-for-data1');
const data = await response.json();
MyComponent.cache['data1'] = data;
this.setState({ data1: data });
}
}
}
- 持久化缓存:使用
localStorage
或者 sessionStorage
进行持久化缓存。在数据加载后,将数据存储到本地存储中,下次加载时先从本地存储读取。注意处理数据的过期问题,可以在存储数据时同时存储时间戳,判断数据是否过期。
4. 处理组件卸载时的问题
- 内存泄漏:确保在组件卸载时清除所有与该组件相关的定时器、事件监听器等。例如,如果在组件中使用了
setInterval
,在 componentWillUnmount
中清除它。
componentDidMount() {
this.timer = setInterval(() => {
// some code
}, 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
- 未完成的异步请求:可以使用
AbortController
来取消未完成的异步请求。在发起请求时创建 AbortController
实例,并在 componentWillUnmount
中调用 abort
方法。例如:
class MyComponent extends Component {
constructor(props) {
super(props);
this.controller = new AbortController();
}
async componentDidMount() {
try {
const response = await fetch('api-url', { signal: this.controller.signal });
const data = await response.json();
this.setState({ data });
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request aborted');
} else {
console.error('Error loading data:', error);
}
}
}
componentWillUnmount() {
this.controller.abort();
}
}