Give me realtime example of using match, location and history

In React Router, the match, location, and history objects are passed as props to the component rendered by a <Route> component. These objects provide information about the current route and allow you to perform navigation.

  1. match: The match object contains information about how the current route matches the URL. It contains properties such as params, path, url, etc. Here’s an example of how to use the match object to access dynamic parts of the URL:
import { BrowserRouter as Router, Route } from 'react-router-dom'

function User({ match }) {
  return <h1>Welcome {match.params.username}</h1>;
}

function App() {
  return (
    <Router>
      <Route path="/users/:username" component={User} />
    </Router>
  );
}

In this example, we have a route that matches URLs of the form /users/:username, where :username is a dynamic part of the URL. We are using the match object to access the value of :username in the User component and display a welcome message.

  1. location: The location object contains information about the current URL and the state of the browser. It contains properties such as pathname, search, hash, state, etc. Here’s an example of how to use the location object to display the current URL:
import { BrowserRouter as Router, Route } from 'react-router-dom'

function Location({ location }) {
  return <h1>You are currently on: {location.pathname}</h1>;
}

function App() {
  return (
    <Router>
      <Route path="/" component={Location} />
    </Router>
  );
}

In this example, we have a route that matches the root path /, we are using the location object to access the pathname property and display the current URL in the Location component.

  1. history: The history object contains methods that allow you to navigate between routes. It contains methods such as push, replace, go, goBack, goForward, etc. Here’s an example of how to use the history object to navigate to a different route:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

function About({ history }) {
  return (
    <div>
      <h1>About</h1>
      <button onClick={() => history.push('/')}>Go to Home</button>
    </div>
  );
}

function App() {
  return (
    <Router>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
      </nav>
      <Route path="/" exact component={Home} />
      <Route path="/about" component={About} />
    </Router>
  );
}

In this example, we have a route that matches the path /about, we are using the history object to access the push method in the About component,

In router, what’s the difference between handling router component as attribute and component as children ?

In React Router, there are two main ways to define a route: as an attribute of a <Route> component, or as a child of a <Route> component.

  1. Handling route as an attribute: When you define a route as an attribute, you pass the component that should be rendered for that route as a prop to the <Route> component. For example:
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    <Router>
      <Route path="/" exact component={Home} />
      <Route path="/about" component={About} />
      <Route path="/contact" component={Contact} />
    </Router>
  );
}

This way of defining a route is the most common, it is simple and easy to use, however it won’t allow you to access the match, location and history props of the <Route> component, unless you use the withRouter higher-order component.

  1. Handling route as children: When you define a route as a child, you pass the component that should be rendered for that route as a child of the <Route> component. For example:
import { BrowserRouter as Router, Route } from 'react-router-dom'

function App() {
  return (
    <Router>
      <Route path="/" exact>
        <Home />
      </Route>
      <Route path="/about">
        <About />
      </Route>
      <Route path="/contact">
        <Contact />
      </Route>
    </Router>
  );
}

This way of defining a route is less common, but it allows you to access the match, location and history props of the <Route> component without using the withRouter higher-order component. This allows you to access the routing context in the child component, it’s more flexible, but it may make your codebase more complex.

In summary, handling the route as an attribute is a simpler and more straightforward way of defining routes, while handling the route as children allows you to have more control and access to the routing context in the child component.

what is the usage of switch in react-router-dom?

In React Router, the <Switch> component is used to group a set of <Route> components together and only render the first route that matches the current URL. This is useful when you have multiple routes that could potentially match the current URL, and you want to ensure that only one of them is rendered at a time.

Here’s an example of how to use the <Switch> component:

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

function App() {
  return (
    <Router>
      <div>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
          <Link to="/contact">Contact</Link>
        </nav>

        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
          <Route path="*" component={NotFound} />
        </Switch>
      </div>
    </Router>
  );
}

In this example, the <Switch> component is used to group the <Route> components together. The <Route> components are defined as children of the <Switch> component, and they will only be rendered if their path prop matches the current URL.

In this example, if the user navigates to the root path ‘/’, the Home component will be rendered since it has the exact prop. If the user navigates to ‘/about’ or ‘/contact’ the corresponding component will be rendered. And if the user navigates to any other path, the NotFound component will be rendered, since the last <Route path="*" component={NotFound} /> has a catch-all path * and it will match any path that doesn’t match the other routes.

It’s important to note that the <Route> components should be in the order of most specific to least specific, meaning the catch-all routes should be the last one to be defined.

Handling routing in difference react versions with examples

In React, routing refers to the process of handling navigation between different parts of the application. The way routing is handled can differ depending on the version of React you are using.

  1. React v16.3 and below: In versions of React prior to v16.4, routing was typically handled using third-party libraries such as React Router. For example, in React v16.3, you could use React Router v4 to handle routing like this:
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

function App() {
  return (
    <Router>
      <div>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
          <Link to="/contact">Contact</Link>
        </nav>

        <Route path="/" exact component={Home} />
        <Route path="/about" component={About} />
        <Route path="/contact" component={Contact} />
      </div>
    </Router>
  );
}
  1. React v16.4 and above: Starting with React v16.4, React introduced a new feature called React Router Hooks, which allows for handling routing using hooks instead of higher-order components. Here’s an example of how to handle routing using React Router Hooks:
import { useRoutes, A } from 'hookrouter'

const routes = {
  '/': () => <Home />,
  '/about': () => <About />,
  '/contact': () => <Contact />
}

function App() {
  const routeResult = useRoutes(routes)
  return (
    <div>
      <nav>
        <A href="/">Home</A>
        <A href="/about">About</A>
        <A href="/contact">Contact</A>
      </nav>
      {routeResult}
    </div>
  )
}

It’s important to note that React Router Hooks is not a standalone library, but rather a feature built into React itself.

Another option for handling routing in React 16.4 and above is the use of Suspense which allows you to load the components lazily or asynchronously.

It is always recommended to use the latest version of React to take advantage of the new features and improvements. However, you can use any version of React that suits your project’s needs, and use the routing methods that are compatible with that version.

How to create a custom hook in react

A custom hook is a function that encapsulates reusable logic in a React application. It allows you to extract component logic into a reusable function that can be shared across multiple components.

To create a custom hook, you need to follow a few conventions:

  1. The name of the custom hook should start with the word “use”. This is a convention that helps identify custom hooks and distinguish them from regular functions.
  2. The custom hook should contain all the logic that you want to reuse. This can include logic for managing state, handling events, making API calls, etc.
  3. The custom hook should return any values that you want to make available to the consuming component.

Here is an example of a custom hook that fetches data from an API and returns the data and a loading status:

import { useState, useEffect } from 'react';

function useApi(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchData() {
      const response = await fetch(url);
      const json = await response.json();
      setData(json);
      setLoading(false);
    }

    fetchData();
  }, [url]);

  return { data, loading };
}

This custom hook can be used in a React component like this:

import { useApi } from './useApi';

function MyComponent() {
  const { data, loading } = useApi('https://api.example.com/endpoint');

  if (loading) {
    return <p>Loading...</p>;
  }

  return (
    <ul>
      {data.map((item) => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>