Dva: match.url

Created on 21 Dec 2017  ·  6Comments  ·  Source: dvajs/dva

currently i need to dispatch from componentDidMount to use match.url from router

// route='/user/:userId'
  componentDidMount() {
    const { location } = this.props;
    this.props.dispatch({
      type: "user/query",
      payload: {
        userId: this.props.match.params.userId,
      },
    });
  }

its not optimal, i can see in hackernews dva clone you can do it from setup subscription as well but you need to duplicate route matchning, not optimal either.

Is there anyway match can be provided to dva model subscription like history?

Most helpful comment

@andriijas dva will inject params through this.props, so you can get userId by this way:

// route='/user/:userId'
  componentDidMount() {
    const { params } = this.props;
    this.props.dispatch({
      type: "user/query",
      payload: {
        userId: params.userId,
      },
    });
  }

All 6 comments

@andriijas dva will inject params through this.props, so you can get userId by this way:

// route='/user/:userId'
  componentDidMount() {
    const { params } = this.props;
    this.props.dispatch({
      type: "user/query",
      payload: {
        userId: params.userId,
      },
    });
  }

@yvanwangl in setup/subscription in model too? basically i dont want to dispatch in componentDidMount

@andriijas Hi, if you want to get userId in subscription, you can use path-to-regexp by this way,

import pathToRegexp from 'path-to-regexp';

subscriptions: {
    setup({ dispatch, history }) {
      history.listen(({ pathname }) => {
        const match = pathToRegexp('/user/:userId').exec(pathname);
        if (match) {
           const userId = match[1];
           dispatch({
              type: "user/query",
              payload: {
                  userId
              },
            });
         }
      });
    },
  },

@yvanwangl yes ive seen it in hackernews dva clone but not ideal to duplicate url matching, react router is already doing it, there is no way to proxy react router match as argument to setup in dva/dva-core?

like this.

subscriptions: {
  setup({ dispatch, history, match }) {
    history.listen(({ pathname }) => {
      dispatch({
        type: "user/query",
        payload: {
          userId: match.userId
        },
      });     
    });
  }
}

@andriijas Hi, i read dva source code based your question, and i find in packages/dva/index.js file where have a function patchHistory

function patchHistory(history) {
    const oldListen = history.listen;
    history.listen = (callback) => {
        callback(history.location);
        return oldListen.call(history, callback);
    };
    return history;
}

here is the magic. When we use history.listen , dva will execute the callback one time, then it register the callback to origin history.listen which is provided by history library.
So in the dva's history.listen function, dva does not know your path pattern, such as '/user/:userId', so it can not parse the parameters(userId) for you.

ah, react router already uses path-to-regex so its already in my bundle, well, then its a nobrainer. thanks for taking your time @yvanwangl .

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MiaoXingGua picture MiaoXingGua  ·  3Comments

mclouvem picture mclouvem  ·  4Comments

itiwll picture itiwll  ·  4Comments

huyawei picture huyawei  ·  3Comments

pengfeiWang picture pengfeiWang  ·  3Comments