Categories
React

How to Send Data from a Child React Component to the Parent Component?

Sometimes in our React app, we’ve to send data from a child component to its parent component.

In this article, we’ll look at how to send data from a child React component to its parent.

Pass a Function to the Child Component

To pass data from a parent component to the child, we can pass a function to a child component as a prop.

For instance, we can write:

import React, { useState } from "react";

const Counter = ({ parentCallback }) => {
  const [count, setCount] = useState(0);

  return (
    <button
      onClick={() => {
        const newValue = count + 1;
        setCount(newValue);
        parentCallback(newValue);
      }}
    >
      Click me {count}
    </button>
  );
};

export default function App() {
  const callback = (val) => {
    console.log(val);
  };

  return (
    <div>
      <Counter parentCallback={callback} />
    </div>
  );
}

We have the Counter component that takes the parentCallback prop.

In the component, we have the count state created from the useState hook.

Then we have a button with the onClick callback that calls the parentCallback with newValue .

In the App component, we have the callback function that we pass into the Counter component as the value of the parentCallback prop.

Now when we click on the Click me button, we should see the console.log function run with val being the value we pass into parentCallback in Counter .

Conclusion

We can send data from a child React component to the parent component by passing in a function from the parent to the child.

Then in the child component, we can call it with the arguments we want to pass the argument values back to the parent component.

Categories
React

How to Handle an Input with React Hooks?

Handling input values is something that we’ve to do often in our React components.

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

Using the useState Hook

To make an input’s value usable in our React component, we’ve to set the input value as a state’s value.

To do this, we can use the useState hook.

For instance, we can write:

import React from "react";

export default function App() {
  const [inputValue, setInputValue] = React.useState("");

  const onChangeHandler = (event) => {
    setInputValue(event.target.value);
  };

  return (
    <div>
      <input
        type="text"
        name="name"
        onChange={onChangeHandler}
        value={inputValue}
      />
      <p>{inputValue}</p>
    </div>
  );
}

We call the useState hook to return an array with the inputValue state and the setInputValue function to set the inputValue state.

Then we define the onChangeHandler function with the event parameter that calls the setInputValue to set the inputValue state.

event.target.value has the input value.

And then we add an input element and pass in the onChangeHandler event handler and the inputValue state into the onChange and value props respectively.

Then we show the inputValue .

We set the value prop to inputValue so we’ll see what we typed into the input.

If we use inputs often, we may also want to put the input logic in a hook:

import React, { useState } from "react";

const useInput = ({ type }) => {
  const [value, setValue] = useState("");
  const input = (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
      type={type}
    />
  );
  return [value, input];
};

export default function App() {
  const [username, userInput] = useInput({ type: "text" });

  return (
    <div>
      {userInput}
      <p>{username}</p>
    </div>
  );
}

We create the useInput hook that takes an object with thew type property so we can set the input type.

Then we call useInput in App to use it.

We put the userInput component in the div and the username , which has the input value.

The hook has the same logic as we have before.

So we see the inputted value rendered when we type into the input.

Conclusion

We can handle input values by calling a state setter function with the input value so we can use the input value in our component.

Categories
React

How to use Throttle or Debounce with React Hook?

Sometimes, we may want to delay or throttle the number of times a piece of code is run in our React component.

In this article, we’ll look at how to throttle or denounce code with React hooks.

Using the Lodash Throttle Function

Lodash comes with the throttle function to let us limit a function to run once in a given time interval.

For instance, we can write:

import React, { useEffect, useRef, useState } from "react";
import { throttle } from "lodash";

export default function App() {
  const [value, setValue] = useState(0);
  const throttled = useRef(throttle((newValue) => console.log(newValue), 1000));

  useEffect(() => throttled.current(value), [value]);

  return <button onClick={() => setValue(value + 1)}>{value}</button>;
}

We call throttle with the function that we want to run and the time interval in milliseconds.

Therefore, the function runs once every 1000 milliseconds at the maximum.

We put th throttled function in the useRef hook to set the throttled function as the value of throttled.current .

This will cache the function between re-renders so it won’t be recreated on every render.

We then call the function we created in the useEffect callback.

So when we click on the button, we see the throttled function runs every 1-second max.

Use the useCallback Hook to Store the Throttled Function

We can replace the ref with the useCallback hook.

For instance, we can write:

import React, { useCallback, useEffect, useState } from "react";
import { throttle } from "lodash";

export default function App() {
  const [value, setValue] = useState(0);
  const throttled = useCallback(
    throttle((newValue) => console.log(newValue), 1000),
    []
  );

  useEffect(() => throttled(value), [value]);

  return <button onClick={() => setValue(value + 1)}>{value}</button>;
}

We just pass in our throttled function into the useCallback hook to cache the function between re-renders.

And we get the same result as before.

Debouncing Functions

Debouncing functions means we call a function after a delay.

To do this, we can create our own hook by writing:

import React, { useCallback, useEffect, useState } from "react";

const useDebouncedEffect = (effect, delay, deps) => {
  const callback = useCallback(effect, deps);

  useEffect(() => {
    const handler = setTimeout(() => {
      callback();
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [callback, delay]);
};

export default function App() {
  const [value, setValue] = useState(0);

  useDebouncedEffect(() => console.log(value), 1000, [value]);

  return <button onClick={() => setValue(value + 1)}>{value}</button>;
}

We create the useDebouncedEffect hook by calling setTimeout in the useEffect callback.

The callback we call is passed in from the effect function.

We call useCallback to cache the effect function so that it won’t be recreated every time the component is rendered.

deps has the dependencies we want to watch. When the value changes, useCallback will recreate the function.

setTimeout returns a timer object so we can use that to clear it when the component unmounts.

When we unmount the component, we call clearTimeout to clear the timer.

In App , we use the useDebouncedEffect hook with a callback that we want to run after a delay.

Now when we click on the button, we wait 1000 milliseconds until the callback is run.

Conclusion

We can add throttle and denounce easily with React.

Categories
React

How to Make the React useEffect Hook Not Run on Initial Render?

Sometimes, we may want to make our useEffect callback not run on initial render.

In this article, we’ll look at how to make the React useEffect callback not run on initial render.

Store the Render State in a Ref

We can create a hook to check whether the first render is done before running the code we want.

To do this, we write:

import React, { useEffect, useRef, useState } from "react";

const useDidMountEffect = (func, deps) => {
  const didMount = useRef(false);

  useEffect(() => {
    if (didMount.current) {
      func();
    } else {
      didMount.current = true;
    }
  }, deps);
};

export default function App() {
  const [count, setCount] = useState(0);

  useDidMountEffect(() => {
    console.log("second render");
  });

  return (
    <div className="App">
      <button onClick={() => setCount((c) => c + 1)}>increment</button>
      <p>{count}</p>
    </div>
  );
}

We create the useDidMountEffect hook to track whether the first render is done.

We do this with the didMount ref.

We have the useEffect hook that runs on when the deps array is changed.

If it’s the first render, we set didMount.current to true .

Otherwise, we run the func function.

In App , we have the count state which is updated when we click on the increment button.

We also pass a callback to the useDidMountEffect hook which we created.

When we click on the increment button, we see 'second render' logged after the first render.

Conclusion

We can make the React useEffect callback not run on the first render by creating a ref that keeps track of whether the first render is done.

Then we can check the ref’s value to see when the first render is done and run the function we want when the first render is done.

Categories
React

What is the Equivalent of the componentDidMount Method in a React Function/Hooks Component?

When we’re creating React components with classes, we run our code that loads when the component mounts in the componentDidMount hook.

However, with React components, this isn’t available.

In this article, we’ll look at how to produce the same result with the componentDidMount hook within React function components.

The useEffect Hook

To run code only when the component mounts, we can use the useEffect hook.

If we pass in an empty array as the 2nd argument, then the useEffect callback in the 1st argument will only run when the component mounts.

For instance, we can write:

import React, { useEffect } from "react";

export default function App() {
  useEffect(() => {
    console.log("mounted");
  }, []);

  return <div className="App"></div>;
}

Now we should only see the 'mounted' string logged when we mount the component.

React Hooks Equivalent of componentDidUpdate

The equivalent of the componentDidUpdate lifecycle method is also the useEffect hook.

componentDidUpdate runs when a state or prop changes values.

We can do the same thing with useEffect by passing in the state or prop values we want to watch into the array we pass into the 2nd argument of useEffect .

For instance, we can write:

import React, { useEffect, useState } from "react";

const Count = ({ count }) => {
  useEffect(() => {
    console.log(count);
  }, [count]);

  return <p>{count}</p>;
};

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <button onClick={() => setCount((c) => c + 1)}>increment</button>
      <Count count={count} />
    </div>
  );
}

to watch the count prop for updates with the useEffect hook in the Count component.

To watch a state, we can write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(count);
  }, [count]);

  return (
    <div className="App">
      <button onClick={() => setCount((c) => c + 1)}>increment</button>
      <p>{count}</p>
    </div>
  );
}

We watch the count state the same way with the useEffect hook.

React Hooks Equivalent of componentWillUnmount

The componentWillUnmount lifecycle method in a React class component lets us run code when we unmount a component.

We can do the same thing with the useEffect hook again.

We just have to return a function in the useEffect callback to do this.

The function we return will run when the component unmounts.

For instance, we can write:

import React, { useEffect } from "react";

export default function App() {
  useEffect(() => {
    console.log("mounted");
    return () => {
      console.log("unmounted");
    };
  }, []);

  return <div className="App"></div>;
}

to return a function in th useEffect callback.

Then we should see 'unmounted' when we unmount the App component.

Conclusion

We can use the useEffect hook in React function components to do the things that lifecycle methods can do in class components.