Categories
React Answers

How to Go Back to the Previous Page with React Router v5?

To go back to the previous page with React Router v5, we can use the useHistory hook.

For instance, we write:

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useHistory
} from "react-router-dom";

const Foo = () => {
  const history = useHistory();

  return (
    <div>
      <button onClick={history.goBack}>Back</button>
      <p>foo</p>
    </div>
  );
};

const Bar = () => {
  const history = useHistory();

  return (
    <div>
      <button onClick={history.goBack}>Back</button>
      <p>bar</p>
    </div>
  );
};

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/foo">foo</Link>
          </li>
          <li>
            <Link to="/bar">bar</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/foo" children={<Foo />} />
          <Route path="/bar" children={<Bar />} />
        </Switch>
      </div>
    </Router>
  );
}

We have the Foo and Bar components which calls the useHistory hook.

In both components, we set the history.goBack method as the value of the onClick prop.

history.goBack lets us go back to the previous page.

In App, we have 2 Links that’s set to go to /foo and /bar respectively.

And we have 2 Routes that’s set to render Foo and Bar when we go to /foo and /bar respectively.

Therefore, when we click on the links and we click Back, we go to the previous page.

Categories
React Answers

How to Wrap One Component into Another with React?

Sometimes, we want to wrap one component into another with React.

In this article, we’ll look at how to wrap one component into another with React.

Wrap One Component into Another with React

To wrap one component into another with React, we add the children prop into the parent component.

For instance, we write:

import React from "react";

const Wrapper = ({ children }) => (
  <div>
    <div>header</div>
    <div>{children}</div>
    <div>footer</div>
  </div>
);

const Child = ({ name }) => <div>Hello {name}</div>;

export default function App() {
  return (
    <Wrapper>
      <Child name="foo" />
    </Wrapper>
  );
}

We create the Wrapper component that accepts the children prop.

And we put children in a div.

Next, we create the Child component that takes the name prop and renders some text.

In App, we wrap Wrapper around Child so that Child is set as a value in the children array.

Therefore, we see:

header
Hello foo
footer

rendered.

Conclusion

To wrap one component into another with React, we add the children prop into the parent component.

Categories
React Answers

How to scroll to top on every transition with React Router v5?

Sometimes, we want to scroll to top on every transition with React Router v5.

In this article, we’ll look at how to scroll to top on every transition with React Router v5.

Scroll to Top on Every Transition with React Router v5

To scroll to top on every transition with React Router v5, we can create a component that scrolls to the top every time we change routes and wrap that around the route components.

For instance, we can write:

import React, { useEffect } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  withRouter
} from "react-router-dom";

const ScrollToTop = ({ history, children }) => {
  useEffect(() => {
    const unlisten = history.listen(() => {
      window.scrollTo(0, 0);
    });
    return () => {
      unlisten();
    };
  }, [history]);

  return <>{children}</>;
};

const ScrollToTopWithRouter = withRouter(ScrollToTop);

const Foo = () => {
  return (
    <div>
      {Array(100)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
};

const Bar = () => {
  return (
    <div>
      {Array(100)
        .fill()
        .map((_, i) => (
          <p key={i}>{i}</p>
        ))}
    </div>
  );
};

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/foo">foo</Link>
          </li>
          <li>
            <Link to="/bar">bar</Link>
          </li>
        </ul>
        <ScrollToTopWithRouter>
          <Switch>
            <Route path="/foo" children={<Foo />} />
            <Route path="/bar" children={<Bar />} />
          </Switch>
        </ScrollToTopWithRouter>
      </div>
    </Router>
  );
}

We create the Foo and Bar components which we use as the route components.

Then we create the ScrollToTop component that listens for route changes with the history.listen method in the useEffect callback.

In the history.listen callback, we call window.scrollTo(0, 0) to scroll to the top when the route changes.

And we call the unlisten method in the function we return in the useEffect callback when the component unmounts.

We render the children components, which contains the route components.

Next, we call the withRouter function with ScrollToTop to return a component that we can wrap around the route components to listen for route changes.

Then in App, we add the Links and the Routes so that when we click the Links the components set as the values of Route‘s children prop would be rendered.

Therefore, each time we click on the links, we should see that the page is scrolled to the top.

Conclusion

To scroll to top on every transition with React Router v5, we can create a component that scrolls to the top every time we change routes and wrap that around the route components.

Categories
React Answers

How to Add Optional Path Parameter with React Router v5?

Sometimes, we want to add optional path parameter with React Router v5.

In this article, we’ll look at how to add optional path parameter with React Router v5.

Add Optional Path Parameter with React Router v5

To add optional path parameter with React Router v5, we can add a ? after the route parameter placeholder.

For instance, we write:

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useParams
} from "react-router-dom";

const Child = () => {
  const { id, slug } = useParams();

  return (
    <div>
      <h3>ID: {id}</h3>
      <h3>slug: {slug}</h3>
    </div>
  );
};

export default function App() {
  return (
    <Router>
      <div>
        <h2>Accounts</h2>

        <ul>
          <li>
            <Link to="/1/foo">foo</Link>
          </li>
          <li>
            <Link to="/1">bar</Link>
          </li>
        </ul>

        <Switch>
          <Route path="/:id/:slug?" children={<Child />} />
        </Switch>
      </div>
    </Router>
  );
}

We have the Route component that has the path prop set to '/:id/:slug?'.

And we make the slug parameter optional by adding the ? after it.

Also, we added links with the path set to a path with and without the second parameter respectively.

In the Child component, we use the useParams hook to get the value of both route parameters.

When we click in the foo link, we see that both id and slug have values.

And when we click on the bar link, we see only id is set.

We set the children prop to the Child component so that it’s rendered when we click on the links.

Conclusion

To add optional path parameter with React Router v5, we can add a ? after the route parameter placeholder.

Categories
JavaScript Answers

How to Retrieve Data from a JavaScript ReadableStream Object?

Sometimes, we want to retrieve data from a JavaScript ReadableStream object.

In this article, we’ll look at how to retrieve data from a JavaScript ReadableStream object.

Retrieve Data from a JavaScript ReadableStream Object

To retrieve data from a JavaScript ReadableStream object, we need to call a conversion method to convert the ReadableStream to the actual data we can use.

For instance, we write:

(async () => {
  const response = await fetch("https://httpbin.org/ip");
  const body = await response.json();
  console.log(body)
})()

to make a GET request to https://httpbin.org/ip with fetch.

fetch returns a promise that resolves to a ReadableStream object which we assigned to response.

Then to convert that to the response data by calling the json method since the response data is serialized into JSON format.

json also returns a promise so we have to use await on that and assign the resolved value to body.

Therefore, body should have the data from the ReadableStream object.

Conclusion

To retrieve data from a JavaScript ReadableStream object, we need to call a conversion method to convert the ReadableStream to the actual data we can use.