Exploring React Hooks: useEffect, useRef, Portals and Controlled/Uncontrolled Components

Exploring React Hooks: useEffect, useRef, Portals and Controlled/Uncontrolled Components

ยท

7 min read

React Hooks were introduced in React 16.8, and they have changed the way we write and think about React components. Hooks provide a way to handle state, side-effects and other features in functional components, making it easier and more consistent to manage the lifecycle of a component. In this blog post, we'll explore some of the most commonly used hooks in React: useEffect, useRef, and portals, and also controlled and uncontrolled components.

Introduction to React hooks and why they are useful :

React Hooks are functions that allow you to use state and other React features in functional components. Prior to React Hooks, state and lifecycle methods were only available to class components. With the introduction of Hooks, functional components can now have the same capabilities as class components, making it easier to write and manage your components.

Hooks provide a more direct way to work with state, side-effects and other features in functional components. They make it easier to manage the lifecycle of a component, and make it more consistent across different components.

Hooks are also much easier to understand, they are less verbose, and they don't require the use of this, making them easier to reason about and less prone to errors.

React Hooks make it easier to build complex and powerful applications in a more maintainable and scalable way. They are a great tool for anyone who wants to work with React, and are a must-know for any React developer.


Explanation of useEffect and when to use it, with examples:

useEffect is a hook in React that allows you to synchronize a component with an external system. It is used to handle side effects, such as fetching data, setting up event listeners, or updating the DOM in response to a change in props or state.

Here's an example of how you might use useEffect to fetch data when a component mounts:

import { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://my-api.com/data')
      .then(response => response.json())
      .then(data => setData(data));
  }, []);

  return <div>{data ? <MyPresentationalComponent data={data} /> : <LoadingSpinner />}</div>;
}

In this example, the useEffect hook is set up to fetch data from an API when the component is first rendered. The empty array [] passed as the second argument ensures that the effect only runs on the initial render and not on subsequent updates.

Now you're confusing about what is second argument and why we want to add in our code???? Don't worry I'll explain with example

In the useEffect hook, the second argument is called the dependencies array It is used to tell React which values from the component's props or state the effect depends on. When any of the values in the dependencies array change, React will re-run the effect. If you pass an empty array [] as the dependencies, React will only run the effect on the initial render and not on subsequent updates.

lets look on example,Here's an example of how you might use the dependencies array to fetch data only when a specific prop changes :

import { useEffect, useState } from 'react';

function MyComponent({ id }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(`https://my-api.com/data/${id}`)
      .then(response => response.json())
      .then(data => setData(data));
  }, [id]);

  return <div>{data ? 
             <MyPresentationalComponent data={data} /> :
              <LoadingSpinner />}
              </div>;
}

In this example, the useEffect hook is set up to fetch data from an API when the id prop changes. The id prop is passed in the dependencies array, so React will re-run the effect whenever the id prop changes.


Explanation of useRef and when to use it, with examples:

In react useRef is a hook that allows you to create a reference to a DOM element or a component. This can be useful when you need to access the underlying DOM node, for example, to focus an input field or to measure the size of an element.

Here's an example of how you might use useRef to focus an input field when a component mounts:

import { useRef } from 'react';

function MyComponent() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus();
    inputRef.current.value="shubham";

//pass refernce to Dom
  }, []);

  return <input ref={inputRef} />;
}

In this example, the useRef hook is used to create a reference to the input element, and the useEffect hook is used to focus the input when the component is first rendered.


Explanation of portals and how to use them with useRef and useEffect.

A portal is a way to render a component or an element outside of its parent component. You can use a combination of useRef and useEffect to create a portal in React.

Here's an example of how you might use a portal to render a tooltip outside of the component that triggers it:

import { useRef, useEffect } from 'react';

function MyData({ name, isOpen }) {
  const containerRef = useRef(null);

  useEffect(() => {
    if (!isOpen) {
      return;
    }
    const container = document.createElement('div');
    document.body.appendChild(container);
    containerRef.current = container;
    return () => {
      document.body.removeChild(container);
    };
  }, [isOpen]);

  return containerRef.current ? createPortal(children, containerRef.current) : null;
}

In the portal example I gave, the children prop is used to specify the content of the portal. The isOpen prop is used to control whether the portal should be open or closed. The useEffect hook is used to create and append the container element to the body of the document when the isOpen prop is true, and to remove the container when the isOpen prop is false. The createPortal function is used to render the children into the container element.

In simple terms, Portals are a way of rendering a component in a different place of the DOM tree than its parent component, it allows to render a component outside of the main app tree, it is useful to create things like modals, tooltips, and dialogs.


Comparison of controlled and uncontrolled components, with examples:

In React, a controlled component is a component that has its state and behavior controlled by its parent component. This means that the parent component is responsible for keeping track of the component's state and handling any changes to that state.

Here's an simple example of a controlled input component:

import React from 'react';

function ControlledInput({ value, onChange }) {
  return <input value={value} onChange={onChange} />;
}

function ParentComponent() {
  const [inputValue, setInputValue] = useState('');

  function handleInputChange(event) {
    setInputValue(event.target.value);
  }

  return <ControlledInput value={inputValue} onChange={handleInputChange} />;
}

here basically , the parentComponents is responsible for keeping track of the input's value in its state and passing that value as a prop to the controlledInput component. The parentComponent also handles any changes to the input's value by passing an onChange prop that updates the state.

On the other hand, an uncontrolled component is a component that manages its own state internally. This means that the component is responsible for keeping track of its own state and handling any changes to that state.

Here's an example of an uncontrolled input component: using Ref

import React, { useRef } from 'react';

function UncontrolledInput() {
  const myRef= useRef(null);

  function handleButtonClick() {
    console.log(myRef.current.value);
//type input "shubham" it will log value as shubham without state its simple way but Its affect react we used rarley 
  }

  return (
    <>
      <input ref={myRef} />
      <button onClick={handleButtonClick}>Log My Value</button>
    </>
  );
}

In this example, the UncontrolledInput component manages its own state internally by using the useRef hook to create a reference to the input element. The component can then access the input's value directly from the reference.

Both controlled and uncontrolled components have their own use cases. Controlled components are useful for keeping the parent component in control of the component state and behavior. Uncontrolled components are useful for keeping the component in control of its own state and behavior.


Conclusion and further resources for learning more about React hooks and other advanced topic:

React Hooks provide a powerful and flexible way to manage the lifecycle of a component. This blog post has covered some of the most commonly used hooks in React, including useEffect, useRef and portals, and also the concept of controlled and uncontrolled components. But there are many other hooks and features in React that are worth exploring. To learn more, check out the official React documentation on Hooks and the React blog. Additionally, there are many tutorials and articles available online that can help you take your React skills to the next level.


We hope that you found this post valuable and informative. If you have any questions or feedback, don't hesitate to reach out to me. My name is Shubham Kadam and you can contact me via email at (), or connect with me on LinkedIn at Linkedln*. I'm always happy to help, and I look forward to hearing from you. Let's continue to learn and grow together in the React ecosystem.

Thanks for reading, and happy coding!

Best,

"Shubham Kadam"

ย