解决React-中已挂载组件不能执行componentDidMount钩子函数的问题

2,225 阅读1分钟

转自:jeezlee/www.pickerlee.com

Issue descripttion

假如我们有如下路由:

<Route path="articles/:articleId" component={Article} />

这时我们从articles/1跳转至articles/2componentDidMount钩子函数不会按照预期执行, 原因是对react来说这2个页面是相同的组件,或者说articles/1组件不会销毁,同样也不会执行componentDidMount

Solution

componentWillReceiveProps钩子函数中手动触发componentWillUnmountcomponentDidMount函数。

装饰器代码如下

/**
 * 该装饰器函数接受一个或多个连续的字符串
 * eg:routeStateChnageToReload('state') or routeStateChnageToReload('state1', 'state2')
 */
const routeStateChnageToReload = (...states) => {
	return target => {
		const oldWillUnmount = target.prototype.componentWillUnmount;
		const oldDidMount = target.prototype.componentDidMount;
		const oldWillReceiveProps = target.prototype.componentWillReceiveProps;

		target.prototype.componentWillReceiveProps = function(nextProps) {
			const changed = Boolean(states.find(state => {
				return this.props.routeParams[state] !== nextProps.routeParams[state];
			}));
			if (changed) {
				oldWillUnmount && oldWillUnmount.call(this);
				oldDidMount && oldDidMount.call(this);
			}
			oldWillReceiveProps && oldWillReceiveProps.call(this, nextProps);
		};
	};
};

使用方式如下:

@routeStateChnageToReload('articleId')
export default class Article extends React.Component {}