1

I have a React application built using React-Router-Dom for navigation. The pages are very heavy on use of tables of data that can be opened in a CRUD form. Due to the amount of records we have in the tables, it's not uncommon for the user to apply sorting, filtering, and paging to the tables in order to find a desired record.

As a fairly standard web application, we have a navigation bar on the left-hand side of the page. This is built up of NavLinks.

The main body of the application is a component, MainPanel, that is almost entirely just a series of Route components within a Switch:

  <Switch>
    <Route path="/page1" component={ComponentOne} />
    <Route path="/page2" component={ComponentTwo} />
  </Switch>

I now have a request from above that when a user selects one of the NavLinks, it should act as a "reset" for everything in the main body of the page. In particular, this should act as a "reset" for all the settings of the table (sort, filter, page, etc.).

This seems like it should almost be trivial, as all I have to do is trigger a re-render of the main panel of the page holding the table. However, I can't find anything in the documentation for React-Router-Dom that holds the key to this.

Anybody got any idea what I'm missing? Is there no easy/right way to say, "When clicking this link, always re-render the MainPanel?

GarrettMurphy
  • 279
  • 3
  • 16

2 Answers2

1

You could keep a value in state, e.g. called panelKey, that you use as key prop for the main panel. You then give panelKey a new value when the the link is clicked, and React will throw away the main panel and create an entirely new component.

Example

class Timer extends React.Component {
  timer = null;
  state = { count: 0 };

  componentDidMount() {
    this.timer = setInterval(() => {
      this.setState(prevState => ({ count: prevState.count + 1 }));
    }, 1000);
  }

  componentWillUnmount() {
    clearInterval(this.timer);
  }

  render() {
    return <div>{this.state.count}</div>;
  }
}

class MainPanel extends React.Component {
  state = { panelKey: 1 };

  onClick = () => {
    this.setState(prevState => ({ panelKey: prevState.panelKey + 1 }));
  };

  render() {
    return (
      <div key={this.state.panelKey}>
        <button onClick={this.onClick}> Reset Panel </button>
        <Timer />
      </div>
    );
  }
}

ReactDOM.render(<MainPanel />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
Tholle
  • 83,208
  • 13
  • 152
  • 148
-1

I see you have listed react-redux in the tags, why not dispatch a custom action to notify other components that filters should be reset?

import { LOCATION_CHANGE } from 'react-router-redux';
import { resetFilter } from './filterActions.js';

const resetFilterMiddleware = ({ dispatch }) => next => action => {
    // Listen for a location chnage
    if(action.type === LOCATION_CHANGE){
        dispatch(resetFilter()); // { type: 'RESET_FILTER' } or something along the lines
    }

    next(action);
}

export default resetFilterMiddleware;
nikksan
  • 2,699
  • 2
  • 16
  • 25
  • I don't think this would ever work, as there is no location change; we're talking about selecting the same link, which should never fire that event. – GarrettMurphy Aug 07 '18 at 16:26
  • it depends on the way you have implemented the navigation, if you are using `dispatch(push('/example'))` then it will work, regardless if the user is on the same page – nikksan Aug 07 '18 at 21:37