blog
blog copied to clipboard
react 开发中,组件生命周期与异步操作之间的一个注意点
react 开发过程中,组件是必不可少的,而在一些实际的业务组件里,通常会包含一些异步操作,比如网络请求等。当组件已经被卸载了之后,异步回调处理中进行的一些比如 setState
等操作会存在内存泄漏的风险。
处理方式
对组件的 componentWillUnmount
事件做处理,当组件被卸载的时候,要不就去停止掉网络请求,要不就对 setState
等敏感操作进行判断。
比如,下面一个小组件的处理,可以参考一下(unmounted
变量是关键):
/**
* 图片组件:自动获取图片大小
*/
import React, { Component } from 'react';
import { Image, Dimensions } from 'react-native';
const WinWidth = Dimensions.get('window').width;
export default class AutoSizedImage extends Component {
constructor(props) {
super(props);
this.state = {
finalSize: {
width: 0,
height: 0,
},
};
this.unmounted = false; // 组件是否已被卸载
}
static defaultProps = {
maxWidth: WinWidth,
style: {},
source: {
uri: '',
},
};
componentWillUnmount() {
this.unmounted = true;
}
componentDidMount() {
//avoid repaint if width/height is given
if (this.props.style.width || this.props.style.height) {
return;
}
// 不限定宽度的话,就取屏幕宽度
const maxWidth = Math.min(this.props.maxWidth, WinWidth);
Image.getSize(this.props.source.uri, (w, h) => { // 异步操作回调
if (this.unmounted) { // 组件已卸载,不做操作
console.log('[AutoSizedImage] component unmounted, abort.');
return;
}
const finalSize = {
width: w,
height: h,
};
if (w > maxWidth) {
finalSize.width = maxWidth;
const ratio = finalSize.width / w;
finalSize.height = h * ratio;
}
this.setState({
finalSize,
});
});
}
render() {
return (
<Image
{...this.props}
resizeMode={'contain'}
style={[
this.props.style,
this.state.finalSize.width && this.state.finalSize.height
? this.state.finalSize
: null,
]}
/>
);
}
}
其他更多处理方式网上一大把,大家可以自行谷歌或者百度!!!