0

I have two base routes that each use a parameter "/categories/:category" and "/types/:type". I also have a navbar that has a dropdown menu for each of the routes and their child params. If I use the navbar links to navigate between the routes the app renders as expected but if I navigate within either route, there is no re-render. This is problematic because the parameter in each case is used to display different contents. Refreshing the page will render the correct content.

The official advice (https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md) is to use a Higher Order Component or to pass the location prop down. This is what I would like to do and should be simple, but where I run into difficulty. When I try to pass the location prop down the typescript compiler complains: (41,36): Property 'location' does not exist on type 'IntrinsicAttributes & PageListProps & { children?: ReactNode; }'.

// App.tsx
class App extends React.Component<any> {
  public render() {
    return (
      <Router>
        <div className="App">
          <header className="App-header">
            <Logo />
            <h1 className="App-title">Directory</h1>
          </header>
          <NavBar />
          <Switch>
            <Route exact={true} path="/" component={ABWs} />

            <Route path="/categories/:category" component={PagesByCategory} />
            <Route path="/types/:type" component={PagesByType} />
          </Switch>
        </div>
      </Router>
    );
  }
}

// PagesByCategory.tsx
import axios from "axios";
import * as React from "react";
import { RouteComponentProps } from "react-router-dom";
import { PageProps } from "../components/Page";
import PageList from "../components/PageList";

interface MatchParams {
  category: string;
}

export interface PagesByCategoryProps
  extends RouteComponentProps<MatchParams> {}

export interface PagesByCategoryState {
  pages: PageProps[];
}

export default class PagesByCategory extends React.Component<
  PagesByCategoryProps,
  PagesByCategoryState
> {
  public state = {
    pages: []
  };

  public componentDidMount() {
    const { category } = this.props.match.params;
    axios
      .get(`http://localhost:9000?categories=${category}`)
      .then(res => {
        //tslint:disable
        console.log(res.data);
        return res;
      })
      .then(res => this.setState({ pages: res.data }));
  }

  public render() {
    const { pages } = this.state;
    const { location } = this.props;
    return <PageList pages={pages} location={location} />;
  }
}
Emil
  • 249
  • 1
  • 2
  • 14
  • It is not that the location is not passed, it is. The problem is that you are using `componentDidMount` to fetch the data when the component is not re-mounted on location change, but merely re-rendered. – Gabriele Petrioli Jun 22 '18 at 13:30
  • Thanks for your reply. Where would you suggest the data fetching occur? The accepted answer on the suggested question this duplicates references a demo made by Ryan Florence that according to a comment predates React Router v1. Other advise I've seen (https://www.robinwieruch.de/react-fetching-data/) recommends using componentDidMount or the now deprecated componentWillMount. Thanks again :) – Emil Jun 23 '18 at 02:30
  • 1
    Found my answer (componentDidUpdate) here: https://stackoverflow.com/questions/37627648/correct-way-to-fetch-data-when-switching-route-on-same-level-in-react-router – Emil Jun 23 '18 at 04:15

0 Answers0