redux devtool 一次崩溃的bug的解决

bug 描述

还是很久之前在准备使用redux devtool的时候,结果安装好插件之后,令人崩溃的事情就出现了,整个浏览器立马崩了,再加上mac的电风扇本来就差,嗡嗡的令人崩溃。
当时加上项目比较忙,所以暂时就没有使用redux devtool来进行调试,最近找了点时间,准备重新看下,毕竟放着也不是个事。

switch (action.type) {
    case GET_SIDEMENU_CONFIG_SUC:
      console.log(
        "%c===========begin=========",
        "background: #000; color: #bada55"
      );
      console.log("ddsd");
      console.log(
        "%c===========end==========",
        "background: #000; color: #bada55"
      );
      return update(state, { $set: transForm(action.payload) });
    default:
      return state;
  }

[站外图片上传中...(image-e08f3-1550837612008)]

可以看到在疯狂的发dispatch请求,结果就是导致浏览器崩溃,内存耗尽。

问题分析

1,刚开始以为是action里边这里有个比较复杂的转换逻辑函数影响的,排查了不是。
2,觉得是不是一直代码里边有循环一直在发,全局搜了下,唯一的一次dispatch的时候,就是在请求成功的时候,但是请求了一次之后,就不会有任何地方在重新dispatch了。
3,然后就在测试是不是action.type有问题,是不是名字和redux devtool有冲突,改过来改过去,没解决问题。
4,最后干脆想直接删除该SIDEMENU的dispacth,可是现在竟然变成了其它的action.type在疯狂的接受了。
5,后来一想这么搞不是办法,删了一个又来了一个,还是到源头那边去搞,于是直接到了router那边去看。
router那边的代码如下:


              
              
            
          }
        >
          
            {/*  */}
            
          
        

当然这是简化之后的,asyncComp 是用来动态的加载reducer和component的,可是就算这样简化之后,仍然是浏览器死机。
6,然后就想是不是和这段代码有关系,于是去把这段代码


              
              
            
          }
        >
          
            {/*  */}
            
          
        

替换成这样的代码

ddss

结果是好的,页面现在正常了,
于是就想是不是和asyncComp这个函数有关系呢,于是就去看了下函数

const asyncComp = (store, modName, config = { extra: [] }) => props => {
  const Comp = lazy(() => {
    const modKey = modName;
    const keys = [modName, ...config.extra];
    const reducers = keys.map(key => {
      return import(`../reducers/${key}/index`);
    });
    return Promise.all(reducers)
      .then(result => {
        injectReducer(store, { keys, reducers: result });
        return import(/* webpackChunkName: "[request]" */ `./${modName}`);
      })
      .catch(error => console.error(`asyncComp${error}`));
  });

  return ;
};

感觉没什么问题,然后就在injectReducer的地方,打了断点,果然他妈的疯狂的在触发,不断的触发,不断的触发,现在可以得出判断上面不断触发action.type是因为不断的插入reducer。
到了这里因为是injectReducer的问题
injectReducer的代码如下:

export const injectReducer = (store, { key, reducer, keys, reducers }) => {
  // 针对一个组件中有多个store
  if (keys && reducers) {
    keys.forEach((key, index) => {
      store.asyncReducers[key] = reducers[index].default;
    });
  } else {
    store.asyncReducers[key] = reducer;
  }
  store.replaceReducer(makeRootReducer(store.asyncReducers));
};

感觉也没什么问题,不过这里看到了不断的replaceReducer,感觉应该和replaceReducer有关系。
7,google了下redux devtool 导致不断的dispatch的问题,好像也没有头绪,资料也很少,于是到redux devtool的github下找issuse,也没有什么类似的,于是去看了下faq,发现这样一段

@@INIT or REPLACE action resets the state of the app or last actions RE-APPLIED

@@redux/REPLACE (or @@INIT) is used internally when the application is hot reloaded. When you use store.replaceReducer the effect will be the same as for hot-reloading, where the extension is recomputing all the history again. To avoid that set shouldHotReload parameter to false.
于是就找到了解决办法,就是得设置shouldhotreload为false
代码如下:

const composeEnhancers = composeWithDevTools({
    shouldHotReload: false
  });
  const store = createStore(
    combineReducers({
      Common: commonReducer
    }),
    initialState,
    composeEnhancers(applyMiddleware(...middleware))
  );

问题得到解决。

反思

1,这个问题按说应该很多人可以遇到,hot-reload和redux和redux devtool应该好多人使用,可是为什么网上竟然没什么资料。
2,其实一开始就基本定位到和redux devtool有关系,但是不知道关系在哪,这个时候可以直接去github上寻找第一手资料,这样可以少走很多弯路。
3,特别复杂的问题,可以大事化小,小事化了,不断的尝试不断的缩小范围

你可能感兴趣的:(redux devtool 一次崩溃的bug的解决)