Search code examples
reactjsreact-reduxreact-routerconnected-react-router

React-router v5 updates the URL but doesn't render nested component


I created an application using react, react-router, react-redux, connected-react-router and I have the following structure:

- app
  - admin
    - category
      - categoryList
      - categoryAdd

My idea is to execute the following app flow:

/admin -> /admin/category -> /admin/category/add

but for some reason I can't see the last component(CategoryAdd) rendered.

Code(sandbox link in the end):

index.js

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { Route, Switch, Link } from "react-router-dom"; 
import { ConnectedRouter } from "connected-react-router";
import configureStore, { history } from "./configureStore";

import AdminPage from "./AdminPage";
import Category from "./Category";

const store = configureStore(/* provide initial state if any */);

ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <>
        <Link to="/admin/category">Category</Link>
        <Switch>
          <Route exact path="/admin" component={AdminPage} />
          <Route exact path="/admin/category" component={Category} />
        </Switch>
      </>
    </ConnectedRouter>
  </Provider>,
  document.getElementById("root")
);

AdminPage.js

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

export default function AdminPage() {
  return (
    <div style={{ border: "1px solid black", margin: 20 }}>
      <div>AdminPage</div>
      <Link to="/admin/category">Catgory page link</Link>
    </div>
  );
}

Category.js

import React from "react";
import { Route, Switch } from "react-router-dom";
import { withRouter } from "react-router-dom";
import CategoryList from "./CategoryList";
import CategoryAdd from "./CategoryAdd";

function Category() {
  return (
    <Switch>
      <Route path={`/admin/category`} render={() => <CategoryList />} />
      <Route path={`/admin/category/add`} render={() => <CategoryAdd />} />
    </Switch>
  );
}

export default withRouter(Category);

CategoryList.js

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

export default function CategoryList() {
  return (
    <div style={{ border: "1px solid black", margin: 20 }}>
      CategoryTable <Link to="/admin/category/add">Add</Link>
    </div>
  );
}

CategoryAdd.js

export default function Add() {
  return <div style={{ border: "1px solid black", margin: 20 }}>Add Page</div>;
}

Here is the sandbox: https://codesandbox.io/embed/dark-star-3fhs0


Solution

  • Your using Switch which only match one route, so your second routes in index.js and Category component will never be rendered.

    1) Remove Switch component and exact route props in index.js

    ReactDOM.render(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <>
            <Link to="/admin/category">Category</Link>
            <Route path="/admin" component={AdminPage} />
            <Route path="/admin/category" component={Category} />
          </>
        </ConnectedRouter>
      </Provider>,
      document.getElementById("root")
    );
    

    2) Remove Switch in Category

    function Category() {
      return (
        <>
          <Route path={`/admin/category`} render={() => <CategoryList />} />
          <Route path={`/admin/category/add`} render={() => <CategoryAdd />} />
        </>
      );
    }
    

    That works in your code sandbox but your CategoryAdd component is broken because you don't import React. So add it in first line :

    import React from 'react';
    

    Result : enter image description here