Categories
React Answers

How to check history previous location before goBack() with React Router v4?

To check history previous location before goBack() with React Router v4, we can save the pathname from the previous location in the Link‘s to prop’s state property.

For instance, we write

<Link
  to={{ pathname: "/graph/1", state: { from: this.props.location.pathname } }}
/>;

to set the state to the value of the current URL before we click on the Link by setting state to { from: this.props.location.pathname }.

We can do the same with history.push by writing

history.push({
  pathname: "/graph/1",
  state: {
    from: this.props.location.pathname,
  },
});

this.props.location.pathname has the URL path of the current page.

Categories
React Answers

How to use Context API with React Router v4?

Sometimes, we want to use Context API with React Router v4.

In this article, we’ll look at how to use Context API with React Router v4.

How to use Context API with React Router v4?

To use Context API with React Router v4, we wrap the Context.Provider component around our route components.

For instance, we write

Store.js

import React, { createContext, useReducer } from "react";
import Reducer from "./reducer.js";

const initialState = {
  //...
};

const Store = ({ children }) => {
  const [state, dispatch] = useReducer(Reducer, initialState);

  return (
    <Context.Provider value={[state, dispatch]}>{children}</Context.Provider>
  );
};

export const Context = createContext(initialState);
export default Store;

to define the Store component that wraps the Context.Provider around the children prop.

children has the components that we put inside Store.

Then in App.js, we write

const App = () => {
  return (
    <BrowserRouter>
      <Switch>
        <Route
          exact
          path="/"
          render={(props) => (
            <Store>
              <Home {...props} />
            </Store>
          )}
        />
        <Route
          exact
          path="/about"
          render={(props) => (
            <Store>
              <About {...props} />
            </Store>
          )}
        />
        <Route
          exact
          path="/login"
          render={(props) => (
            <Store>
              <Login {...props} />
            </Store>
          )}
        />
      </Switch>
    </BrowserRouter>
  );
};

to set the render prop of each Route component to a function that renders Store with the route component inside.

As a result, Home, About, and Store has access to the Context we defined in Store.js.

Conclusion

To use Context API with React Router v4, we wrap the Context.Provider component around our route components.

Categories
React Answers

How to set activeClassName for wrapper element of Link or IndexLink in React Router?

Sometimes, we want to set activeClassName for wrapper element of Link or IndexLink in React Router.

In this article, we’ll look at how to set activeClassName for wrapper element of Link or IndexLink in React Router.

How to set activeClassName for wrapper element of Link or IndexLink in React Router?

To set activeClassName for wrapper element of Link or IndexLink in React Router, we can set the className prop of our wrapper element.

For instance, we write

import React, { PropTypes } from "react";
import { Route, Link } from "react-router-dom";
import styles from "./styles.less";

export default function NavItem({ children, to, exact }) {
  return (
    <Route
      path={to}
      exact={exact}
      children={({ match }) => (
        <li className={match ? styles.activeRoute : null}>
          <Link to={to}>{children}</Link>
        </li>
      )}
    />
  );
}

to set the li‘s className prop to the class we want.

And we wrap that around the Link so the li will be rendered as the parent of the anchor rendered by the Link.

Conclusion

To set activeClassName for wrapper element of Link or IndexLink in React Router, we can set the className prop of our wrapper element.

Categories
React Answers

How to fix the “A Router may have only one child element” error with React Router?

Sometimes, we want to fix the "A Router may have only one child element" error with React Router.

In this article, we’ll look at how to fix the "A Router may have only one child element" error with React Router.

How to fix the "A Router may have only one child element" error with React Router?

To fix the "A Router may have only one child element" error with React Router, we should wrap our components within the Router component with a wrapper component.

For instance, we write

<Router>
  <div>
    <Route exact path="/" component={BaseLayer} />
    <Route path="/editor" component={App} store={store} />
  </div>
</Router>

to wrap a div around the Route components so that the error goes away.

Conclusion

To fix the "A Router may have only one child element" error with React Router, we should wrap our components within the Router component with a wrapper component.

Categories
React Answers

How to use multiple layouts with React Router v4?

Sometimes, we want to use multiple layouts with React Router v4.

In this article, we’ll look at how to use multiple layouts with React Router v4.

How to use multiple layouts with React Router v4?

To use multiple layouts with React Router v4, we just wrap our layout component around the routes.

For instance, we write

const Pages = () => {
  return (
    <ReactRouter>
      <Switch>
        <Route path="/comingsoon" component={ComingSoon} exact />
        <Route>
          <MainLayout>
            <Switch>
              <Route path="/home" exact>
                <Home />
              </Route>
              <Route path="/login" exact>
                <Login />
              </Route>
              <Route path="/useraccount" exact>
                <UserAccount />
              </Route>
            </Switch>
          </MainLayout>
        </Route>
      </Switch>
    </ReactRouter>
  );
};

to wrap MainLayout around some Route components.

Then the layout in Mainlayout would be applied to the components inside, which includes Home , Login, and UserAccount.

Conclusion

To use multiple layouts with React Router v4, we just wrap our layout component around the routes.