Proper way to conditionally Render pages in React

Without using React Router, I wanted to simply render pages by adding/removing a class. I have three list items in a nav and three pages. The code I wrote works, but I don’t think I am doing it in a “React way”. As in, I think I am directly manipulating the DOM in my toggle function in the parent component by doing [...list.children]. This is just my own experimenting and wanted to see if anyone else could share their insights.

Here is the link to the code: https://codesandbox.io/s/magical-framework-7t75s

1 Like

Yeah, you’re very much overcomplicating things by manipulating the DOM. I use reach router rather than react router, so apologies for slightly different syntax, but RR is almost the same (a set of <Route path="somepath" component="NameOfComponentToLoad"> in a <Switch> component)

<Router>
  <Foo path="/foo" />
  <Bar path="/bar" />
  <Baz path="/" />
</Router>

When the url is “mysite/foo”, the <Foo> component renders, when the url is “mysite/bar”, the <Bar> component renders, etc etc. That’s it.

1 Like

Right, I thought that my method wasn’t the right approach when using React. I have used React Router before and it is obviously a great solution, and on real projects I would use that instead of re-inventing the wheel. But I just wanted to see how such functionality could be achieved without using React Router or another library. Was just curious to know if someone else took a similar dive into this issue. Thanks for your response.

1 Like

So a few things:

  • if you actually want to change things dependent on URL (so the point of the router), you have to use the browser History API – there’s not a choice here, because you need to be able to change the URL programmatically without reloading the page (which would cause a refresh and blow away the state of the app). You can do this directly, without a dependency, but you are still in a position where the thing you want to do is say “render component X if the url is /foo, render component Y if the url is /bar”. There is a good, very small library which wraps the History API for React (just called history) which makes this easy, and is what React Router is built on.
  • If you want to show/hide via CSS, same thing applies, but you should not really be changing class names to do this: there is no need, because you can literally just set the style property inline in the JSX. And if you really want it seperated into CSS, just change the className directly, do not try to get at the DOM. This is what I mean by overcomplicating – you have direct access to these elements, and you can very simply change attributes, you don’t need to ever dig into the DOM, there’s no need to add another complex layer of abstraction over the top.
  • Again, it’s is preferable to not render the components if you don’t need them, but there are some benefits to hiding them via CSS (animation becomes easier for one thing, because you can then transition visibility in and out with ease).

Edit: https://medium.com/@jeswin/you-dont-need-react-router-or-any-other-router-9e2c7b036b0

Note that just using the History API is easy for easy things, but you generally end up reinventing React Router as it gets more complex. Also I’d :100: recommend trying Reach Router, it’s simpler than React Router and is built to be completely accessible, I’ve found it to be a really good thing.

1 Like

Awesome. Thank you so much for the detailed suggestions. I will definitely checkout the browser History API. I just personally like trying to get a finer understanding of how certain things work on the web. I’ll take your other suggestions into consideration as well.

2 Likes