1

We have a sidebar that uses history.push to navigate from one page to another in a SPA. When this happens context providers are preserved but the page's useState goes back to its default value. I looked at the code for Link and its not doing anything different than the history push.

We can rewrite to use Link but I read that history push should work and that is all Link is doing anyway. The code below uses route render but have tried with just the JSX like others also.

<Router history={history}>
  <div className={classes.body}>
    <div className={classes.root}>
      <Drawer appConfig={appConfig} />
      <div style={{ width: '100%', height: '100vh', overflow: 'hidden' }}>
        <Switch>
          <Route type="public" path="/dialogs" exact render={Markets} />
          <Route type="public" path="/notifications" exact>
            <Notifications />
          </Route>
          <Route type="public" path="/:marketId" exact>
            <Market />
          </Route>
          <Route type="public" path="/:marketId/about" exact>
            <About />
          </Route>
          <Route>
            <PageNotFound />
          </Route>
        </Switch>
      </div>
    </div>
  </div>
</Router>
function Markets(props) {
  const { intl } = props;
  const { marketDetails, loading } = useAsyncMarketContext();
  const [addMode, setAddMode] = useState(false);

  function toggleAdd() {
    setAddMode(!addMode);
  }

  function onMarketSave() {
    toggleAdd();
  }

  return (
    <Activity
      title={intl.formatMessage({ id: 'sidebarNavDialogs' })}
      isLoading={loading}
      titleButtons={<IconButton onClick={toggleAdd}><AddIcon /></IconButton>}
    >
      <div>
      {!addMode && <MarketsList markets={marketDetails} /> }
      {addMode && <MarketAdd onCancel={toggleAdd} onSave={onMarketSave} />}
      </div>
    </Activity>
  );
}

The expectation is that if addMode is true it will retain its value when clicking to "/notifications" and back.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 1
    When you go to `Notifications` from `Markets`, you unmount the first and render the second. When going back, you remount `Markets` which initializes with a state at `false` so it is an expected behavior. If you want to keep that state between pages, you should set it in the parent component. – Gaël S Oct 02 '19 at 16:22
  • @GaëlS no what you are saying is not correct https://stackoverflow.com/questions/48150567/react-router-difference-between-component-and-render – David Israel Oct 02 '19 at 17:09
  • my bad, I read `component` and not `render` inside the `Route` – Gaël S Oct 02 '19 at 17:35
  • Update - okay it is https://github.com/ReactTraining/react-router/issues/4988 - basically I have to somehow hide the unused components or else they are removed from the dom. – David Israel Oct 02 '19 at 18:04
  • Just put the state up in the components tree and pass it down to Markets. – Gaël S Oct 02 '19 at 19:32

0 Answers0