- 在 React 类组件中使用生命周期方法加载数据
componentDidMount
:
- 这是 React 类组件挂载后调用的生命周期方法。在这个方法里发起 API 请求是很常见的做法。例如:
import React, { Component } from'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
fetch('your - api - url')
.then(response => response.json())
.then(data => this.setState({ data }));
}
render() {
const { data } = this.state;
return (
<div>
{data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>}
</div>
);
}
}
export default MyComponent;
componentDidUpdate
:
- 此方法在组件更新后调用。如果要根据 props 的变化来重新获取数据,可以在这里进行判断和请求。例如:
import React, { Component } from'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps) {
if (prevProps.someProp!== this.props.someProp) {
this.fetchData();
}
}
fetchData() {
fetch('your - api - url')
.then(response => response.json())
.then(data => this.setState({ data }));
}
render() {
const { data } = this.state;
return (
<div>
{data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>}
</div>
);
}
}
export default MyComponent;
- 防止不必要的重复请求
- 使用状态标记:
- 在发起请求前,设置一个状态标记,例如
isLoading
。如果已经在加载数据,或者数据已经存在且没有触发重新请求的条件(如 props 变化),则不再发起新的请求。
import React, { Component } from'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null,
isLoading: false
};
}
componentDidMount() {
if (!this.state.isLoading &&!this.state.data) {
this.setState({ isLoading: true });
fetch('your - api - url')
.then(response => response.json())
.then(data => {
this.setState({ data, isLoading: false });
});
}
}
componentDidUpdate(prevProps) {
if (prevProps.someProp!== this.props.someProp &&!this.state.isLoading &&!this.state.data) {
this.setState({ isLoading: true });
fetch('your - api - url')
.then(response => response.json())
.then(data => {
this.setState({ data, isLoading: false });
});
}
}
render() {
const { data, isLoading } = this.state;
return (
<div>
{isLoading? <p>Loading...</p> : (data? <p>{JSON.stringify(data)}</p> : <p>Not loaded yet</p>)}
</div>
);
}
}
export default MyComponent;
- 使用缓存:
- 可以创建一个全局的缓存对象,在请求数据前先检查缓存中是否已经有需要的数据。例如:
const dataCache = {};
import React, { Component } from'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
if (!dataCache['your - api - url']) {
fetch('your - api - url')
.then(response => response.json())
.then(data => {
dataCache['your - api - url'] = data;
this.setState({ data });
});
} else {
this.setState({ data: dataCache['your - api - url'] });
}
}
render() {
const { data } = this.state;
return (
<div>
{data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>}
</div>
);
}
}
export default MyComponent;
- 使用
React.memo
或 shouldComponentUpdate
:
React.memo
:对于函数组件,可以使用 React.memo
来包裹组件,它会对 props 进行浅比较。如果 props 没有变化,组件不会重新渲染,也就不会触发数据请求逻辑(前提是数据请求逻辑在 useEffect
依赖数组设置正确的情况下)。例如:
import React, { useEffect, useState } from'react';
const MyComponent = React.memo((props) => {
const [data, setData] = useState(null);
useEffect(() => {
fetch('your - api - url')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<div>
{data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>}
</div>
);
});
export default MyComponent;
- **`shouldComponentUpdate`**:在类组件中,可以重写 `shouldComponentUpdate` 方法,通过比较当前和之前的 props 或 state 来决定是否允许组件更新。如果返回 `false`,组件不会更新,也就不会重复发起请求(前提是请求逻辑在 `componentDidUpdate` 等合适的生命周期方法中)。例如:
import React, { Component } from'react';
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
shouldComponentUpdate(nextProps, nextState) {
// 比较 props 和 state 判断是否需要更新
if (nextProps.someProp === this.props.someProp && nextState.data === this.state.data) {
return false;
}
return true;
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate() {
this.fetchData();
}
fetchData() {
fetch('your - api - url')
.then(response => response.json())
.then(data => this.setState({ data }));
}
render() {
const { data } = this.state;
return (
<div>
{data? <p>{JSON.stringify(data)}</p> : <p>Loading...</p>}
</div>
);
}
}
export default MyComponent;