Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在全局model的history.listen中调用dispatch,同时Link的to属性添加query参数会导致栈溢出 #2693

Closed
feibi opened this issue Jun 25, 2019 · 7 comments · Fixed by dvajs/dva#2230

Comments

@feibi
Copy link
Contributor

feibi commented Jun 25, 2019

What happens?

  1. 全局model调用dispatch
//src/models/test.js 

export default {
  namespace: 'test',
  reducers: {
    updateState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
  subscriptions: {
    setup({ dispatch, history }) {
      return history.listen(location => {
        //这里写会栈溢出
        dispatch({
          type: 'updateState',
          payload: {
            a: 1,
          },
        });
      });
    },
  },
};
  1. Link的to属性添加query参数
// src/pages/list/index.js
import Link from 'umi/link';

export default () => {
  // to加上query会导致栈溢出
  return <Link to={{ pathname: '/user', query: { a: 1 } }}>跳转到user</Link>;
};

两个步骤同时满足就会栈溢出。
在src/pages/list/model.js中dispatch不会栈溢出
Link的to属性不加query不会栈溢出

Mini Showcase Repository(REQUIRED)

Provide a mini GitHub repository which can reproduce the issue.
Use yarn create umi then upload to your GitHub

https://github.com/feibi/umi-bug.git

Expected behavior

  1. 期望全局model与局部model表现一致,不会栈溢出

Context

  • Umi Version: 2.8.3
  • Umi-plugin-react Version: 1.8.4
  • Node Version: v10.15.0
  • Platform: window 10
@Leridy
Copy link

Leridy commented Jul 20, 2019

我也碰到过这个这个问题。。开发环境遇到过,正式环境没有遇到

@yxyufo110
Copy link

我也是这个,有好的解决方法嘛

@sorrycc
Copy link
Member

sorrycc commented Jul 29, 2019

需要花时间看,可能和 react-reudx 升级有关。

@630133368
Copy link

这个问题有点严重鸭~~ 组件里面想跳转一下路由。 只要在订阅里面有diapatch就会栈溢出

@Fuphoenixes
Copy link

Fuphoenixes commented Sep 4, 2019

找到了一种曲线救国的解决办法。
问题产生主要是在 subscriptions的history.listen中调用dispatch,其实需求就是想在路由变化时去处理一些逻辑。
所以可以不使用history.listen而在其他地方监听路由变化,绕开这个bug。
具体写法如下:
第一步在全局layouts/index.js中监听路由变化,因为路由变化时会重新触发这里的render。

// src/layouts/index.js

let oldLocation = {};
const listenRoute = (props)=>{
  const { location, dispatch } = props;
  //路由地址发生变化时,触发 onRouteChange action
  if(location.pathname !== oldLocation.pathname){
    dispatch({
      type:'onRouteChange',
      location
    });
  }
  oldLocation = location;
};

function BasicLayout(props) {
  listenRoute(props)
  return (
    <div>
      {props.children}
    </div>
  );
}

export default BasicLayout;

第二步对应model (这里是 全局global)监听等待匹配 onRouteChange action

// src/models/global.js

export default {
  namespace: 'global',

  state: {
    location: null
  },

  subscriptions:{
    setup({ dispatch }){
      dispatch({ type: 'test'})
    }
  },
  effects: {
    * test(_, { take, put }) {
      while (true) {
        const { location } = yield take('onRouteChange');
        /*
        * 每次路由变化,这里的逻辑都会执行一遍。可以吧原本要写在history.listen中的逻辑放在这里。
        * 这里的location是目标路由的路由信息。
        * */
        yield put({
          type: 'changeState',
          payload :{
            location
          }
        })

      }
    },
  },

  reducers: {
    changeState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};

@xiaohuoni
Copy link
Member

xiaohuoni commented Oct 16, 2019

新版本有这个问题,在 subscriptions 里面调用请求,会无限请求,最终栈溢出

subscriptions: {
    setup({ dispatch, history }) {
      return history.listen(location => {
        //这里写会栈溢出
        dispatch({
          type: 'updateState',
        });
      });
    },
  },

在以下版本没有这个问题

@sorrycc

临时方案:项目中安装 [email protected] ,此方案不适用于二次封装 umi 的库,如 alitajs 等,最终安装的还是测试版

@xty314
Copy link

xty314 commented Oct 25, 2019

一样的问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants