Morzanne
Morzanne

Reputation: 21

Params matching return empty React-router

I am facing an apparently simple problem but it is getting complicating , even with some well written existing topics.

I have a global route

export const createPricingPath = `${catalogRoutes.priceLists.path}/creation/:pricingId?/:step(products|parameters|customers-groups)`;
export const toCreatePricingPath = pathToRegexp.compile(createPricingPath);

As you can see I have a step parameters and an optional one called pricingId.

I have a parent route leading to my top level parent component

    <ProtectedRoute
      exact
      AUTHORIZED_ROLES={[USER_ROLES.PRICING]}
      path={createPricingPath}
      render={props => <PricingCreationPanelContainer {...props} />}
    />

The parent top root component is the following one :

            <SlidePaneProvider route={catalogRoutes.priceLists.path}>
                {({ handleCancel }) => (
                    <Fragment>
                        <PricingCreationPanelHeader handleCancel={handleCancel} {...this.props} />
                        <SlidePaneBody>
                            <PricingContent handleCancel={handleCancel} {...this.props} />
                        </SlidePaneBody>
                    </Fragment>
                )}
            </SlidePaneProvider>

Inside this component we got somme "commun" elements like a PricingCreationHeader and SlidesComponents ( body ect...), and I have a PricingContent which is the children containing my sub-routes and children components.

It looks like this:

const PricingContent = ({ handleCancel, match: { params } }) => {

    return (
        <Switch>
            <ProtectedRoute
                exact
                AUTHORIZED_ROLES={[USER_ROLES.PRICING]}
                path={toCreatePricingPath({ step: 'parameters' })}
                render={props => <PricingCreation {...props} />}
            />
            <ProtectedRoute
                exact
                AUTHORIZED_ROLES={[USER_ROLES.PRICING]}
                path={toCreatePricingPath({ step: 'products', pricingId: params.pricingId })}
                render={props => <PricingProducts {...props} />}
            />
            <ProtectedRoute
                exact
                AUTHORIZED_ROLES={[USER_ROLES.PRICING]}
                path={toCreatePricingPath({ step: 'customers-groups', pricingId: params.pricingId })}
                render={props => <PricingClients handleCancel={handleCancel} {...props} />}
            />
        </Switch>
    )
};

The problem is, I can't figure out why I am not able to get the match.params.pricingId and match.params.step props inside every child component (PricingClients and PricingProducts ). PricingCreation doesnt need pricingId by the way, only the other two.

I do have the impression that everything is clearly well written. The child component should be able to get all the params since the root parent component does.

Maybe it is an architecture problem so every suggestion is welcome ! I went through many existing topics and was not able to find a proper solution.

Thank you very much for helping me !

Upvotes: 1

Views: 458

Answers (1)

Aliaksei Yakubuk
Aliaksei Yakubuk

Reputation: 11

As far as I can see here, path for child routes is specified incorrectly. I dont think that making path dynamically is a good idea. It is enough to specify shortened version of parent path and match.pricingId will be available in child components:

const PricingContent = ({ handleCancel }) => {

    return (
        <Switch>
            <ProtectedRoute
                path={ `${base_path }/creation/:pricingId?/parameters`}
                // other props stay the same
            />
            <ProtectedRoute
                path={ `${base_path}/creation/:pricingId?/products`}
               // other props stay the same
            />
            <ProtectedRoute
                path={ `${base_path}/creation/:pricingId?/customer-groups`}
               // other props stay the same
            />
        </Switch>
    )
};

According to code above base_path is catalogRoutes.priceLists.path.

  1. I think there is no need in :step route param as we have a separate component for every route. In case we still need it, it's possible to do smt like this: .../:step(parameters);
  2. Optional :pricingId? can cause mounting of incorrect component, for example: base_url/products/parameters In this case router is considering "products" as :pricingId route param which is not good=) I often try to avoid optional params in the middle of a path

My apologies if I missed or misunderstood something Thank you

Upvotes: 1

Related Questions