Categories
JavaScript React

How to Handle Forms With React

In this article, we’ll look at how to handle forms with React.


Form Handling

The standard way to handle form input value changes is to handle them with React. This is a technique called controlled components.

We can create controlled components with input, textarea, and select elements. They maintain their own state, and updates are based on user input.

Like with anything else, the component state is updated with setState(). This means that we have to call it with the value of the input elements to update the state with the inputted values.

To update the state with the inputted value, we can write the following:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: "" };
  }
  handleChange(event) {
    this.setState({ name: event.target.value });
  }
  handleSubmit(event) {
    alert(`Name submiited: ${this.state.name}`);
    event.preventDefault();
  }
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>
            Name:
            <input
              type="text"
              value={this.state.name}
              onChange={this.handleChange.bind(this)}
            />
          </label>
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }

In the code above, we have the input element that has an onChange handler which is set to this.handleChange. The handleChange method has the code to update this.state.name with the latest inputted value. event.target.value has the latest value.

Then, we attached an onSubmit handler to the form, which is set to this.handleSubmit.

We call event.preventDefault to prevent the default submit action, so we can run JavaScript code in the handler to display the alert box with the latest inputted value.

The handler methods make it easy to handle input validation. We can also manipulate it there. For example, we can change our input value before updating the state as follows:

handleChange(event) {  
  this.setState({name: event.target.value.toLowerCase()});  
}

We don’t have to create an extra function to change our input to lowercase before setting it to this.state.name.

We have the value prop to set the value to the latest state so that we can see our inputted value.


The textarea Tag

Like with handling input elements, we can handle value changes with textarea elements the same way.

We can write the following to set the state to the latest inputted value:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { essay: "" };
  }
  handleChange(event) {
    this.setState({ essay: event.target.value });
  }
  handleSubmit(event) {
    alert(`Essay submiited: ${this.state.essay}`);
    event.preventDefault();
  }
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>Essay:</label>
          <br />
          <textarea
            type="text"
            value={this.state.essay}
            onChange={this.handleChange.bind(this)}
          />
          <br />
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

It’s pretty much the same as the code for handling inputted values from the input element, but we have a textarea element instead.


The select Tag

The select element creates a drop-down where we can select more values.

We can write the following code to get the selection from the drop-down and set it to the state:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { fruit: "apple" };
  }
  handleChange(event) {
    this.setState({ fruit: event.target.value });
  }
  handleSubmit(event) {
    alert(`Favorite fruit: ${this.state.fruit}`);
    event.preventDefault();
  }
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>Favorite Fruit:</label>
          <br />
          <select
            onChange={this.handleChange.bind(this)}
            value={this.state.fruit}
          >
            <option value="apple">Apple</option>
            <option value="orange">Orange</option>
            <option value="mango">Mango</option>
          </select>
          <br />
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

As we can see, it’s almost the same as the other examples, except that we have a select element with option elements inside instead.

select elements also work for getting multiple selections. We can update the state with all the selections by getting the options available, getting the ones that are selected, and putting them in an array as follows:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { fruits: [] };
  }
  handleChange(event) {
    const options = event.target.options;
    const fruits = [];
    for (const option of options) {
      if (option.selected) {
        fruits.push(option.value);
      }
    }
    this.setState({ fruits });
  }
  handleSubmit(event) {
    alert(`Favorite fruit: ${this.state.fruits.join(",")}`);
    event.preventDefault();
  }
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>Favorite Fruit:</label>
          <br />
          <select
            multiple
            onChange={this.handleChange.bind(this)}
            value={this.state.fruits}
          >
            <option value="apple">Apple</option>
            <option value="orange">Orange</option>
            <option value="mango">Mango</option>
          </select>
          <br />
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

In the code, we have:

handleChange(event) {
  const options = event.target.options;
  const fruits = [];
  for (const option of options) {
    if (option.selected) {
      fruits.push(option.value);
    }
  }
  this.setState({ fruits });
}

In the first line of the function, we have:

const options = event.target.options;

Which has all the options from the select element.

Then, we can loop through the options and check the selected property of each and then push them to the array if selected is true. We then call setState with fruits to update the state with the latest selected values.

In handleSubmit, we can this.state.fruits and call join on it with a comma to convert it to a comma-separated string.

Also, the value prop of the select element takes an array instead of a string. React is smart enough to parse the array and render the selected values.


Handling Multiple Inputs

When we need to handle multiple inputs, we don’t want to make a new onChange handler function for each input. Therefore, we want to make a function that can set all values.

We can do that as follows:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { firstName: "", lastName: "" };
  }
  handleChange(event) {
    const target = event.target;
    const value = target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }
  handleSubmit(event) {
    alert(`Name ${this.state.firstName} ${this.state.lastName}`);
    event.preventDefault();
  }
  render() {
    return (
      <div className="App">
        <form onSubmit={this.handleSubmit.bind(this)}>
          <label>First Name:</label>
          <br />
          <input
            name="firstName"
            onChange={this.handleChange.bind(this)}
            value={this.state.firstName}
          />
          <br />
          <label>Last Name:</label>
          <br />
          <input
            name="lastName"
            onChange={this.handleChange.bind(this)}
            value={this.state.lastName}
          />
          <br />
          <input type="submit" value="Submit" />
        </form>
      </div>
    );
  }
}

In the code above, we have the following handleChange method:

handleChange(event) {
  const target = event.target;
  const value = target.value;
  const name = target.name;
  this.setState({
    [name]: value
  });
}

We get the event.target object and set it to target. The target has the name and value properties that have the input’s name and value attribute values respectively.

Therefore, we can take advantage of ES6’s dynamic object property feature and call setState with the name as the property name and value as the value to update the state.


Conclusion

We should handle input changes by writing controlled components. To do this, we attach an event handler function to the onChange event.

To handle form submit, we attach an onSubmit event handler to the form, and then get the event object from the parameter and call event.preventDefault inside so we can run JavaScript code in the handler.

To handle multiple input changes with one onChange handler, we get the name and value properties from event.target from the handler’s parameter and update it with the dynamic property name feature available since ES6.

Categories
JavaScript

JavaScript Events Handlers- onfocus , oncancel and More

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign event handler to handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we will look at the oncanplaythrough , onchange , onclick , and onclose event handlers.

oncanplaythrough

The oncanplaythrough property let us assign our own event handler function to it to handle the canplaythrough event. This event is triggered when the user agent can play the media and estimates that there’s enough data loaded to play the media all the way to the end without having to stop and buffer for more data. For example, we can listen to the canplaythrough event for a video by adding the following HTML code:

<video width="320" height="240" controls id='video'>  
  <source src="https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4" type="video/mp4">  
</video>

Then in our JavaScript code we can add:

const video = document.getElementById('video');  
video.oncanplaythrough = (event) => {  
  console.log(event);  
}

We can also attach the canplaythrough event listener by using the addEventListener method on the video DOM node instead like in the following code:

const video = document.getElementById('video');  
video.addEventListener('canplaythrough', (event) => {  
  console.log(event);  
});

Either way, we can check if enough parts of the media has been downloaded in order for it to finish by using the readyState property of the media element, which include video and audio elements. The readyState can have one of the following possible values:

  • The constant HAVE_NOTHING or number 0 — there’s no information about the media resource
  • The constant HAVE_METADATA or number 1 — enough parts of the media resource has been downloaded that the metadata attributes are initialized. Seeking won’t raise exceptions in this state or beyond
  • The constant HAVE_CURRENT_DATA or number 2 — there’s enough data available for current playback position, but not enough to actually play more than one frame
  • The constant HAVE_FUTURE_DATA or number 3 — there’s enough data for the current playback position is downloaded, as well as enough data for playing at least a little bit into the future, which means at least 2 frames of video.
  • The constant HAVE_ENOUGH_DATA or number 4 — there’s enough data available, and that the download rate is high enough, that the media can be played through to the end without interruption.

We can get the readyState property of our video element by writing the following code:

const video = document.getElementById('video');  
video.oncanplaythrough = (event) => {  
  console.log(event.target.readyState);  
}

If our video can be played all the way through, we should have 4 logged in the console.log output.

onchange

The onchange property let us assign an event handler to it to handle the change event. The change event is triggered when the user commits a value change to a form control. This may be done by clicking outside of the control or by using the Tab key to switch a different control. For example, we can use it to get the input value of an input element after a user has enter a value to the input and then move the focus outside the input. First we can add the following HTML code:

<input type="text" size="50" id='input' placeholder='Input'>

Then in the JavaScript code, we add:

const input = document.getElementById('input');  
input.onchange = (event) => {  
  console.log(event.target.value);  
}

The value property of the input element will have the text value that we entered into the input element that we added to the HTML code. It’s very helpful for getting the input as the user types and moves between different inputs and moving between different parts of the form.

onclick

We can assign an event handler to the onclick property of an element to do something when the user clicks on an element. The click event is handled by the onclick event handler, which is trigger when the user clicks on the element. It fires after the mousedown and the mouseup event in that order. The click event doesn’t get triggered on non-mouse or touch screen devices. To accommodate these users, we can handle the keydown event. For example, we can use it to get the position of the browser tab that was clicked with the following HTML code:

<p>Click anywhere in this example.</p>  
<div id='message'></div>

We will add the message for tracking the position the mouse is in in the div element.

Then in our JavaScript code, we can write:

const message = document.getElementById('message');  
document.onclick = (event) => {  
  message.innerHTML = `You click coordinate is x = ${event.clientX}, y = ${event.clientY}`;  
}

In the code above, we got the position of the page the mouse was in the when the mouse was clicked on the page. We can use the Event object’s clientX and clientY to get the x and y coordinates of each mouse click respectively. Then when we run the code, then we can see the mouse coordinate wherever the mouse was clicked.

onclose

To get handle the situation when the dialog element has closed, we can use the onclose event handler, since the close event is triggered when it’s closed. Handling the event with the onclose event handler prevents it from bubbling, so parent handlers aren’t notified of the event. Only one onclose handler can be assigned to an object at once. However, if we use the addEventListener to attach the event handler function to our element, then we can get around this limitation. The difference between the close and cancel events is that the close event is triggered no matter which way the dialog box is closed. For example, we can use it like in the following code:

const dialog = document.getElementById('dialog');  
const openButton = document.getElementById('open-button');  
openButton.onclick = () => {  
  dialog.showModal();  
};

dialog.onclose = (event) => {  
  console.log('dialog closed');  
  console.log(event);  
}

Then we have to add the dialog element to our HTML code:

<button id='open-button'>  
  Open Dialog  
</button>  
<dialog id="dialog">  
  <form method="dialog">  
    <p>  
      Dialog  
    </p>  
    <menu>  
      <button id="cancel-button" value="cancel">Cancel</button>  
      <button id="confirmBtn" value="default">Confirm</button>  
    </menu>  
  </form>  
</dialog>

In the code above we added a dialog element to the HTML and get the DOM element for the HTML dialog element with the getElementById method, which gets us has the following methods:

  • close() — a dialog instance method to close the dialog element. An optional string can be passed in as an argument, which updates the returnValue of the dialog , which is useful for indicating which button the user used to closed it.
  • show() — a dialog instance method to display the dialog modelessly, which means we still allow interaction from the outside. It takes no arguments.
  • showModal() — a dialog instance method to display the dialog as a modal over the top of anything else. It displays on the top layer along with a ::backdrop pseudo-element. Interaction with elements outside the dialog is blocked and the content outside can’t be interacted with.

dialog DOM elements also have the following value properties:

  • open — a boolean property that reflects the open HTML attribute, which indicates whether a dialog is open for interaction.
  • returnValue — a string property that sets and returns the return value for the dialog. We can assign it a value directly or we can pass in an argument to the close method to set this property.

We didn’t need to call the close() method to close the dialog box. Having a button is enough. Also, we don’t have to click a button to close the dialog, we can also press the Esc key on our keyboard to do so.

Note that the dialog element isn’t enabled by default on Firefox. To use it in Firefox, we have to set dom.dialog_element.enabled to true in the about:config page. Chrome has this feature enabled by default. Then if we click the ‘Open Dialog’ button that we just made, then we will see a native browser dialog box. Then if we press the Esc key to close the dialog, then the cancel event will be triggered and the event handler function that we assigned to the dialog.oncancel will run. The event parameter of the event handler function will get an Event object, which has the information about the source of the cancel event which is our dialog element. So we would get something like the following in our console.log output:

bubbles: false  
cancelBubble: false  
cancelable: false  
composed: false  
currentTarget: null  
defaultPrevented: false  
eventPhase: 0  
isTrusted: true  
path: (5) [dialog#dialog, body, html, document, Window]  
returnValue: true  
srcElement: dialog#dialog  
target: dialog#dialog  
timeStamp: 3902.0349998027086  
type: "close"

The oncanplaythrough property let us assign our own event handler function to it to handle the canplaythrough event. The canplaythrough event is trigger when the media is complete downloaded so that the browser won’t have to stop and buffer to play the media all the way through. The onchange property let us assign an event handler to it to handle the change event. The change event is triggered when the user commits a value change to a form control. We can assign an event handler to the onclick property of an element to do something when the user clicks on an element. To get handle the situation when the dialog element has closed, we can use the onclose event handler, since the close event is triggered when it’s closed. The close event is different from the cancel event in that the cancel event is only trigger when the Esc key is pressed to close the dialog, but the close event is triggered whatever way the user used to close the dialog.

Categories
JavaScript React

Built-in React Hooks — useCallback, useMemo and Refs

useImperativeHandle

useImperativeHandle customizes the instance value that’s exposed to parent components when using a ref .

For example, we can use it as follows:

function Button(props, ref) {  
  const buttonRef = React.useRef();  
  React.useImperativeHandle(ref, () => ({  
    focus: () => {  
      buttonRef.current.focus();  
    }  
  }));  
  return <button ref={buttonRef}>Button</button>;  
}  
Button = React.forwardRef(Button);

function App() {  
  const buttonRef = React.useRef(null);  
  React.useEffect(() => {  
    buttonRef.current.focus();  
  }, []);  
  return (  
    <>  
      <Button ref={buttonRef} />  
    </>  
  );  
}

In the code above, we have:

React.useImperativeHandle(ref, () => ({  
    focus: () => {  
      buttonRef.current.focus();  
    }  
  }));

to customize the focus method to call buttonRef.current.focus(); .

Then we pass buttonRef in Button to the button ‘s ref as follows:

<button ref={buttonRef}>Button</button>;

Then to make the ref accessible to App , we run:

Button = React.forwardRef(Button);

Then in App , we run:

const buttonRef = React.useRef(null);

to create the ref and:

<Button ref={buttonRef} />

to set buttonRef to our exposed Button ‘s buttonRef after calling forwardRef to expose it to App .

Then we run:

React.useEffect(() => {  
    buttonRef.current.focus();  
  }, []);

to focus the Button component’s button when App first renders.

Conclusion

We can use the useCallback hook to return a memoized callback, which we can call. It takes a callback as an argument and an array of dependencies that were referenced in the callback as the second argument.

useMemo caches values that are computed. It takes a function that returns a value as the first argument, and an array of values that the function depends on as the second argument.

useRef returns a mutable object whose current property is initialized to the initial value and can be passed into the ref prop of an element to set current to the DOM element.

useImperativeHandle customizes the behavior of the DOM element methods of the element that’s exposed via forwardRef to the parent component.

Categories
JavaScript React

Introduction to React Router

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

To build single-page apps, we have to have some way to map URLs to the React component to display.

In this article, we’ll look at the basic usage of React Router.

Installation

To use React Router, we have to install it. We can do that by running:

npm i react-router-dom

Basic Usage

React Router has a few basic components.

BrowserRouter

First, there’s the BrowserRouter to do the routing with the HTML5 history API.

It takes a few props:

  • basename — a string prop for the base URL for all locations.
  • getUserConfirmation — a function prop we use to confirm navigation. Defaults to using window.confirm .
  • forceRefresh — a boolean prop that’s true if we want a full refresh on page navigation. It’s useful for imitating traditional server-render apps.
  • keyLength — a number prop that sets the length of location.key . Defaults to 6.
  • children — a React component to render. Before React 16, we can only use a single child element. If we want to render more than one element, we can wrap it in a div.

Switch

Next, there’s the Switch component. It renders the first child Route or Redirect that matches the location.

Switch renders a route exclusively. Route that matches the location renders inclusively.

Switch will only pick one Route to render.

Route

The Route component is the most important component in React Router.

It’s used to map URLs to components and takes the following props:

  • component — we pass in the component to map the URL to by passing in a component to it.
  • render — this prop takes a function that returns something that we want to render.
  • children — a function prop that lets us render something when the path matches Route ‘s path and render something else otherwise.
  • path — a string or array of strings that are paths to match.
  • exact — a boolean prop to that’s true if we want to render only if a path matches exactly.
  • strict — boolean prop that’s true is we only want to match a path with a trailing slash only when the URL entered has a trailing slash. It has no effect when there’re additional URL segments in location.pathname
  • location — an object prop that tries to match its path in the current history location.
  • sensitive — a boolean prop that true if the path is case-sensitive.

Link

The Link component provides accessible navigation around our app.

It takes the following props:

  • to — a string prop with the path that we want to go to. It’s created by concatenating location’s pathname, search and hash properties.
  • to can also be an object that has the pathname, search, state and hash properties. The pathname is a string that has the path to link to. search is a string of the query parameters, hash is a hash top put in the URL, state is the state to persist to the location.
  • to can also be a function which takes the currentlocation as the argument and returns the location representation as a string as an object.
  • replace — a boolean prop that replaces the current entry in the history stack instead of adding one if true
  • innerRef — a function or ref object that we shouldn’t need if we’re using React Router 5.1 or later with React 16. It lets us access the ref of the component.
  • We can any other attribute to the a tag like title , id , className , etc.

Example

We can use the components above together as follows:

import React from "react";  
import ReactDOM from "react-dom";  
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";  
function Home() {  
  return <h2>Home</h2>;  
}

function Foo() {  
  return <h2>Foo</h2>;  
}

function Bar() {  
  return <h2>Bar</h2>;  
}

function App() {  
  return (  
    <Router>  
      <div>  
        <ul>  
          <li>  
            <Link to="/">Home</Link>  
          </li>  
          <li>  
            <Link to="/foo">Foo</Link>  
          </li>  
          <li>  
            <Link to="/bar">Bar</Link>  
          </li>  
        </ul>  
        <Switch>  
          <Route exact path="/">  
            <Home />  
          </Route>  
          <Route path="/foo">  
            <Foo />  
          </Route>  
          <Route path="/bar">  
            <Bar />  
          </Route>  
        </Switch>  
      </div>  
    </Router>  
  );  
}
const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we have the Home , Foo , and Bar components which display some text.

Then we add Router in App and put all our Route s inside so when we click on the Link s, they’ll display the component we specified.

We have:

<Switch>  
    <Route exact path="/">  
        <Home />  
    </Route>  
    <Route path="/foo">  
        <Foo />  
    </Route>  
    <Route path="/bar">  
        <Bar />  
    </Route>  
</Switch>

In the Switch , we have exact in the first Route to only show Home when we go to / .

Then we define 2 more Route s to show Foo when we go to /foo and Bar when we go to /bar .

Conclusion

We can use React Router to map URLs to components. This lets us create a single-page app since we render components according to URLs on the client-side.

Therefore, we’ll have a self-contained app that works on its own without the server rendering things when we type in URLs.

We have the Link to render links, Route to map URLs to components. Router wraps around anything that needs routing.

Switch renders the first child Route or Redirect that matches the location.

Categories
JavaScript React

Profile React App Performance with the Profile Component

React is a library for creating front end views. It has a big ecosystem of libraries that work with it. Also, we can use it to enhance existing apps.

In this article, we’ll look at how to profile a React app’s performance with the Profiler API.

Profiler API

The Profiler component measures how often a React app renders and what the cost of rendering is.

It helps identify parts of an app that are slow and may benefit from optimizations like memoization.

This component adds overhead, so it’s disabled in the production build.

Basic Usage

We can use it to measure performance as follows:

import React, { Profiler } from "react";  
import ReactDOM from "react-dom";  
import { unstable_trace as trace } from "scheduler/tracing";

class App extends React.Component {  
  constructor(props) {  
    super(props);  
    this.state = { msg: "" };  
  } 

  onRender(  
    id,  
    phase,  
    actualDuration,  
    baseDuration,  
    startTime,  
    commitTime,  
    interactions  
  ) {  
    const performanceData = [  
      `id: ${id}`,  
      `phase: ${phase}`,  
      `actualDuration: ${actualDuration}`,  
      `baseDuration: ${baseDuration}`,  
      `startTime: ${startTime}`,  
      `commitTime: ${commitTime}`,  
      `interactions: ${JSON.stringify([...interactions])}`  
    ].join("\n");  
    console.log(performanceData);  
  } 

  componentDidMount() {  
    trace("initial render", performance.now(), () => {  
      this.setState({ msg: "foo" });  
    });  
  } 

  render() {  
    return (  
      <Profiler id="app" onRender={this.onRender.bind(this)}>  
        <p>{this.state.msg}</p>  
      </Profiler>  
    );  
  }  
}

const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we have the Profiler component wrapped around our main app code in the rendr method.

We add an id prop so that we can identify what part of the React tree was committed if we’re using multiple profilers.

Also, we have an onRender prop which is set the our onRender method that we defined.

onRender is a callback that has the following parameters:

  • id — a string that we set to identify the part of the React component tree that we just committed.
  • phase — a string that can either have the value 'mout' or 'update' . This identifies whether the tree has just been mounted for the first time or re-rendered due to a change in props, state or hooks.
  • actualDuration — a number that shows the time spent rendering the Profiler and its descendants for the current update. This indicates how well the subtree makes use of memoization (e.g. with React.memo , useMemo , shouldComponentUpdate ). This should decrease significant after the initial mount since child components will only be re-rendered if props change
  • baseDuration — a number that indicates the duration of the most recent render time of each individual component within the Profiler tree. This estimates a worst-case cost of rendering
  • startTime — a timestamp when React began rendering the current update
  • commitTime — a timestamp when React committed to the current update. It’s shared between all profilers in a commit, enabling them to be grouped
  • interactions — a Set of interactions that were being traced when render or setState were called.

In the onRender method, we logged all the parameter values, and we get the following when App renders:

id: app  
phase: update  
actualDuration: 0.38499990478157997  
baseDuration: 0.045000109821558  
startTime: 908.5849998518825  
commitTime: 909.2250000685453  
interactions: [{"_count":1,"id":0,"name":"initial render","timestamp":906.7250001244247}]

The interactions output is from the trace method call. It’s tracking the time when the code inside the callback we passed as the last argument of trace we run.

This lets us associate the performance information with the events that caused the app to render.

From the output above, we can see that the render was caused by an update, and it’s because of the initial render interaction that we have in the componentDidMount lifecycle hook.

In the trace function call, we have the string with the name that we set to identify the interaction, performance.now() is a more precise version of Date.now() to get the current date-time which we pass in as the timestamp to start the trace.

The 3rd argument is a callback with the code that we want to trace the interaction for.

Conclusion

We can use the Profiler component to add performance tracking capabilities when we’re developing the app.

It’s useful because we can use it to see what parts of the React app is performing slowly and can benefit from caching or memoization.

To tracking interactions, i.e., the events that caused an update to be scheduled, we can use the unstable_trace function from the scheduler/tracing package to trace the timing of the interactions.