REACT HOOKS: State Hooks

PART II

REACT HOOKS: State Hooks

State Hooks

State lets a component “remember” information like user input. For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.

To add state to a component, use one of these Hooks:

useState:

  • It is a fundamental tool for managing state in functional components.

  • declares a state variable that you can update directly.

  • To handle reactive data, to handle update in UI when there is changes in data. E.G. WITHOUT HOOK

  • This hook allows functional components to manage state within them. Before the introduction of hooks in React, state management was primarily done in class components using the this.state and this.setState methods. However, with the advent of hooks, state management can now be accomplished in functional components as well.

  • BENEFITS

    • PREVENT MANUALLY GRABING HTML ELEMENTS USING VANILLA JS. THEN RE RENDER. POSSIBLE IMPLEMENTATION OF STATE IN REACT

    • The useState hook in React is commonly used for managing and handling local component state within functional components.

  • Here are some common use cases for the useState hook:

    1. Counter or Numeric Input: Managing a numeric value that needs to be incremented or decremented, such as a counter or a numeric input field.

       const [count, setCount] = useState(0);
      
    2. Toggle State: Toggling between two states, like showing/hiding a component or switching between "on" and "off" states.

       const [isOn, setIsOn] = useState(false);
      
    3. Input Form Fields: Managing the state of input fields and form data.

       const [formData, setFormData] = useState({
         username: "",
         password: "",
       });
      
    4. Dropdown Selection: Managing the selected item in a dropdown or select input.

       const [selectedOption, setSelectedOption] = useState("default");
      
    5. Fetching and Storing Data: Managing data fetched from an API or external source.

       const [data, setData] = useState([]);
      
    6. Accordion or Expanding Sections: Controlling the open/closed state of sections in an accordion or a collapsible component.

       const [isExpanded, setIsExpanded] = useState(false);
      
    7. Modal or Dialog State: Managing the visibility and content of modal or dialog boxes.

       const [isModalOpen, setIsModalOpen] = useState(false);
      
    8. User Authentication: Managing the authentication state of a user (e.g., logged in or logged out).

       const [isLoggedIn, setIsLoggedIn] = useState(false);
      
    9. Theme Switching: Switching between light and dark themes.

       const [isDarkTheme, setIsDarkTheme] = useState(false);
      
    10. Error Handling: Managing error messages or displaying error states.

  • IT RETURNS AN ARRAY THAT CAN BE USED WITHIN COMPONENT!

  •   const [error, setError] = useState(null);
    

example

import React, { useState } from "react";

function UseStateEg() {
  const [count, setCount] = useState(0);
  const [inputVal, setInputVal] = useState("");

  function handleChange(event) {
    const newValue = event.target.value;
    setInputVal(newValue);
  }

  return (
    <>
      <div>
        <h1>EXAMPLE 1</h1>
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <h1>EXAMPLE 2</h1>
        <input
          type="text"
          placeholder="Enter Anything.."
          onChange={handleChange}
        />
        <h2>output: {inputVal}</h2>
      </div>
    </>
  );
}

export default UseStateEg;

useReducer:

  • declares a state variable with the update logic inside a reducer function.

  • replacement or alternative to useState hook but with specific benifits

  • when altering more than one state at the same time

  • In React, the useReducer hook is often used to manage more complex state logic compared to the useState hook. It allows you to manage state transitions based on actions dispatched to a reducer function.

  • RETURN TYPE:

    • array of object

    • dispatcher function to perform changes on above defined variable object

  • paramter:

    • reducer function:

    • default value to object variable

useReducer Example

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

const reducer = (state, action) => {
  switch (action.type) {
    case "INCREMENT":
      return { count: state.count + 1, showText: state.showText };
    case "toggleShowText":
      return { count: state.count, showText: !state.showText };
    case "BOTH":
      return { count: state.count + 1, showText: !state.showText };
    default:
      return state;
  }
};

function UseReducerEg() {
  const [state, dispatch] = useReducer(reducer, { count: 0, showText: true });

  return (
    <div>
      <h1>{state.count}</h1>
      <button
        onClick={() => {
          dispatch({ type: "BOTH" });
        }}
      >
        BOTH OPERATION
      </button>
      <button
        onClick={() => {
          dispatch({ type: "INCREMENT" });
        }}
      >
        INCREMENT OPERATION
      </button>
      <button
        onClick={() => {
          dispatch({ type: "toggleShowText" });
        }}
      >
        TOGGLE OPERATION
      </button>
      {state.showText && <p>This is text</p>}
    </div>
  );
}

export default UseReducerEg;

USE CASES

useState:

  1. Simple State:

    • Use useState for managing simple and independent state variables.

    • For components with straightforward state requirements, like counters, toggles, or input fields.

  2. Individual State Values:

    • When you have a single piece of data to track, like a count or a boolean.
  3. Component-Level State:

    • For components where state updates don't depend on the previous state.
  4. Synchronous Updates:

    • When state updates can be handled synchronously and don't require complex logic.

useReducer:

  1. Complex State Logic:

    • Use useReducer when your component's state logic is complex and involves multiple related values.
  2. State Transitions:

    • When state transitions depend on the previous state or when updating one state variable affects others.
  3. Global or Shared State:

    • For managing global or shared state that needs to be coordinated across multiple components.
  4. Multiple State Values:

    • When you have multiple state variables that need to be updated together, ensuring consistency.
  5. Asynchronous Updates:

    • When state updates involve complex logic, asynchronous operations, or dependency on the previous state.
  6. Alternative to useContext:

    • useReducer can be an alternative to useContext for managing global state, especially when the state logic is intricate.

When to Choose:

  • useState: Use when the state logic is simple, updates are independent, and the component doesn't involve complex state transitions or dependencies.

  • useReducer: Opt for when the state logic is more complex, involves multiple related values, or requires coordination between different state variables.