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.

Categories
React Answers

How to target active link when the route is active in Next.js?

Sometimes, we want to target active link when the route is active in Next.js.

In this article, we’ll look at how to target active link when the route is active in Next.js.

How to target active link when the route is active in Next.js?

To target active link when the route is active in Next.js, we can set the className prop to return the class name we want after we check the current route we’re on.

For instance, we write

import Link from "next/link";
import { useRouter } from "next/router";

export const Nav = () => {
  const router = useRouter();

  return (
    <ul>
      <li className={router.pathname === "/" ? "active" : ""}>
        <Link href="/">home</Link>
      </li>
      <li className={router.pathname === "/about" ? "active" : ""}>
        <Link href="/about">about</Link>
      </li>
    </ul>
  );
};

to add the Nav component that calls the useRouter hook to return the router object.

And then we use the router.pathname property to check the current route we’re on.

We then set className to 'active' if router.pathname returns the route value we’re checking again and an empty string otherwise.

Conclusion

To target active link when the route is active in Next.js, we can set the className prop to return the class name we want after we check the current route we’re on.