Store储存历史的数据,我怎么才能unmount的时候清除

#1

当组件unmount之后,下次mount的时候, store还储存着历史的数据,我怎么去清除这种历史数据。只能在willunmount的时候,手动清除吗

#2

手动清除可以,但是比较麻烦,需要手写action,然后在每个reducer中监听。

如果想通用一点,可以先建个action

// keys 为state的key
export function clearState(...keys) {
  return {
    type: CLEAR_STATE,
    keys: keys
  };
}

然后写个高阶组件

import React, {PropTypes, Component} from 'react';
import {clearState} from 'actions';
import {connect} from 'react-redux';

const clearStateWithUnmount = (...stateKeys) => WrappedComponent => {
  if(!stateKeys) {
    return;
  }
  let instance = class extends Component {
    componentWillUnmount() {
      this.props.dispatch(clearState(...stateKeys));
    }

    render() {
      return <WrappedComponent {...this.props}/>;
    }
  };
  return connect(null)(instance);
};

export default ClearStateWithUnmount;

在创建store时,处理一下

// 这里引入所有reducer
const appReducer = combineReducers({
  ...reducers
});
const rootReducer = (state, action) => {
  // 清除指定的state
  if(action.type === CLEAR_STATE) {
    const {type, keys} = action;
    keys.forEach(k => {     
      _.set(state, k, undefined);

     //_.set方法为lodash中的方法,这里将对应的state设为undefined

    });
  }
  return appReducer(state, action);
};
//创建store
const store = createStore(rootReducer);

大功告成,比如你有个user组件

//这里使用装饰器模式,需要babel支持
@clearStateWithUnmount('user')
class User extends Component{
  ...
}
//如果不想用装饰器,可以用一般的写法
clearStateWithUnmount('user')(User)

这样在User组件unmount时候,就清除了相应的store

如果你的state有深层嵌套,比如{user: {name: ‘foo’, age: 12}},这里也同样支持
@clearStateWithUnmount('user.name', 'user.age')

如果不想侵入现有项目,可以做个中间件,原理是一样的

1 Like
#3

单独封装一个清除store的方法很好,我通常都是直接调用原来的dispatch去设置初始化的值,因为有很多state初始化的值都不只是undefined,可能是一个具体的字符串,数字,或者非空数组等。

#4

谢谢你提醒了我,我回头修改下