mgh
mgh

Reputation: 407

Preserve the initial props.history.location.pathname and navigate from there

import React from "react";
import { withRouter, Route } from "react-router";
import { Link } from "react-router-dom";

const Component1 = () => <div>component1</div>;

const Component2 = () => <div>component1</div>;

const Component3 = () => <div>component1</div>;

const Container = (props) => {

  return (
    <div>
      <ul>
        <Link to={`${props.history.location.pathname}component1`}>
          component 1
        </Link>
        <Link to={`${props.history.location.pathname}component2`}>
          component 2
        </Link>
        <Link to={`${props.history.location.pathname}component3`}>
          component 3
        </Link>
      </ul>
      <div>
        <Route
          path={`${props.history.location.pathname}/component1`}
          exact
          component={Component1}
        />
        <Route
          path={`${props.history.location.pathname}/component2`}
          exact
          component={Component2}
        />
        <Route
          path={`${props.history.location.pathname}/component3`}
          exact
          component={Component3}
        />
      </div>
    </div>
  );
};

export default withRouter(Container);

Hey

according to the code above, if the container is at the path localhost:3000/container then when I click the first item, it goes to localhost:3000/container/component1, from there if I click the second option, it goes to localhost:3000/container/component1/component2 whereas the desired functionality is that we go from localhost:3000/container/component1 to localhost:3000/container/component2

I know that I can store the initial props.history.location.pathname (in this case localhost:3000/container/) when component mounts but I feel there should be a neater way to achieve this.

Thank you.

Upvotes: 0

Views: 523

Answers (2)

trebor
trebor

Reputation: 734

Instead of history.location.pathname, you should rather use match.path and match.url.

Create an array of components. Map them in the way as in an example (Person can be your Container). Instead of recursive Person in Route create Routes of your components).

You can also look at my live example (which is a modified version of the example above)

const A = () => <div>a</div>;
const B = () => <div>b</div>

function Container() {
  let { url } = useRouteMatch();

  const components = [A, B];

  return (
    <div>
      <ul>
        {components.map((_, idx) => (
          <li key={idx+1}>
            <Link to={`${url}/component${idx+1}`}>component{idx+1}</Link>
          </li>
        ))}
      </ul>
      <Switch>
        {components.map((component, idx) => (
          <Route path={`${url}/component${idx+1}`} component={component} />
        ))}
      </Switch>
    </div>
  );
}

Upvotes: 1

ibtsam
ibtsam

Reputation: 1710

Ok when defining your routes why are you using location.pathname to define your routes.

Change your routes as

return (
<div>
  <ul>
    <Link to={`container/component1`}>
      component 1
    </Link>
    <Link to={`container/component2`}>
      component 2
    </Link>
    <Link to={`container/component3`}>
      component 3
    </Link>
  </ul>
  <div>
    <Route
      path={`container/component1`}
      exact
      component={Component1}
    />
    <Route
      path={`container/component2`}
      exact
      component={Component2}
    />
    <Route
      path={`container/component3`}
      exact
      component={Component3}
    />
  </div>
</div>
);

Hope it helps

Upvotes: 0

Related Questions