分享个人 Full-Stack JavaScript 项目开发经验
我们知道,在 React 类组件的 componentWillUnmount 生命周期方法中,必须移除定时器、移除事件监听、取消网络请求、销毁第三库实例以及清理任何在 componentDidMount 环节创建的 DOM 元素等。
在使用 react-redux 后,fetch 请求从 React 中剥离。有些时候,我们想在 fetch 获得响应后再调用组件内的方法,如 this.setState,亦不想请求因组件移除而被取消。若获得响应时,组件已经被移除,则会导致互相引用,React 抛出一个错误,告诉你这样会导致内存溢出。
我们可以使用dispatchEvent,利用事件分发和监听机制避免这一问题。下面对这一过程做简单介绍:
定义 actionCreator,接收回调函数的引用。
export function delete_something(ids, cb) {
return function (dispatch) {
// ......
return fetchThenDispatch('request_url','POST', JSON.stringify({ids}), function(json){
// ......
cb && cb();
});
}
}
在容器组件中连接回调函数属性,使其分发这个 Action。
import {connect} from "react-redux";
import {delete_something} from "../actionCreator/list";
import {ListUI} from "../components/list/list";
export const ListContainer = connect(
state => (
// ...
), dispatch => (
{
onDeleteSomething(ids, callback) {
dispatch(delete_something(ids, callback));
}
}
)
)(ListUI);
在 actionCreator 的回调函数中,我们在 window 上分发一个事件,而不是调用组件上下文 this 的方法。需要执行的操作通过组件内的事件监听函数执行,组件移除时,移除这个事件监听。
import React from "react";
class Example extends React.Component {
// ......
clickHandle = ()=> {
// ......
// 在时间处理函数中执行回调函数属性
this.props.onDeleteSomething(this.ids, () => {
// 待 actionCreator 的 fetch 响应后在 window 上分发一个事件;
const event = new Event(this.eventName);
// 也可实用传递参数的自定义事件
// const event = new CustomEvent(this.eventName, {'detail': {your_data: '...'})
// e.detail
window.dispatchEvent(event);
});
};
componentDidMount() {
// ......
window.addEventListener(this.eventName, this.deleteHandle);
}
componentWillUnmount() {
// 移除删除监听
window.removeEventListener(this.eventName, this.deleteHandle);
}
}