分享个人 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.detailwindow.dispatchEvent(event);});};componentDidMount() {// ......window.addEventListener(this.eventName, this.deleteHandle);}componentWillUnmount() {// 移除删除监听window.removeEventListener(this.eventName, this.deleteHandle);}}