Categories
React Answers

How to intercept and handle browser’s back button in React Router v6?

Sometimes, we want to intercept and handle browser’s back button in React Router v6.

In this article, we’ll look at how to intercept and handle browser’s back button in React Router v6.

How to intercept and handle browser’s back button in React Router?

To intercept and handle browser’s back button in React Router, we can listen for changes in the history object with the navigation.listen method.

For instance, we write

import { BrowserHistory } from "history";
import React, { useContext } from "react";
import { UNSAFE_NavigationContext } from "react-router-dom";

export default function usePathname() {
  const [state, setState] = React.useState(window.location.pathname);

  const navigation = useContext(UNSAFE_NavigationContext)
    .navigator;
  React.useLayoutEffect(() => {
    if (navigation) {
      navigation.listen((locationListener) =>
        setState(locationListener.location.pathname)
      );
    }
  }, [navigation]);

  return state;
}

to create the usePathname hook to listen for for navigation with navigation.listen.

We call it with a callback to listen for navigation.

In it, we call setState with locationListener.location.pathname to save the latest URL we navigated to as the value of state.

Conclusion

To intercept and handle browser’s back button in React Router, we can listen for changes in the history object with the navigation.listen method.

Categories
React Answers

How to validate input values with React?

To validate input values with React, we can use react-hook-form.

To install it, we run

npm i react-hook-form

Then we use it by writing

import React from "react";
import useForm from "react-hook-form";

function App() {
  const { register, handleSubmit, errors } = useForm();
  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} />

      <input name="lastname" ref={register({ required: true })} />
      {errors.lastname && "Last name is required."}

      <input name="age" ref={register({ pattern: /\d+/ })} />
      {errors.age && "Please enter number for age."}

      <input type="submit" />
    </form>
  );
}

to call the useForm hook to return an object with a few properties we use.

Then we add a form element with the onSubmit prop set top handleSubmit(onSubmit).

We use handleSubmit to return a function that does form validation before calling onSubmit.

We call register to register form fields and add validation rules.

And we should errors using the errors property.

Categories
React Answers

How to fix div cannot appear as a descendant of p error with React?

To fix div cannot appear as a descendant of p error with React, we should make sure we don’t have divs that are inside p elements.

For instance, we shouldn’t write

<p>
  <div>...</div>
</p>

in our React components.

If we’re using the Material UI Typography component, we can change the component prop so that we don’t render a div inside a p element.

To do this, we write

<Typography component={"span"} variant={"body2"}>
  ...
</Typography>

to set the component prop to 'span' so that Typography doesn’t render a div inside a p element.

Categories
React Answers

How to get something from the state or store inside a React Redux-Saga function?

To get something from the state or store inside a React Redux-Saga function, we call the select function.

For instance, we write

export const getProject = (state) => state.project;

// Saga
export function* saveProjectTask() {
  while (true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject);
    yield call(fetch, "/api/project", { body: project, method: "PUT" });
    yield put({ type: SAVE_PROJECT_SUCCESS });
  }
}

to call select with the getProject to get the project state from the store.

Categories
React Answers

How to respond to the width of an auto-sized DOM element in React?

To respond to the width of an auto-sized DOM element in React,m we can use the react-measure hook.

To install it, we run

npm i react-measure

Then we use it by writing

import * as React from "react";
import Measure from "react-measure";

const MeasuredComp = () => (
  <Measure bounds>
    {({
      measureRef,
      contentRect: {
        bounds: { width },
      },
    }) => <div ref={measureRef}>My width is {width}</div>}
  </Measure>
);

to use the Measure component from react-measure to retuen the width of the div by assigning the measureRef provided as the value of the div’s ref prop.