Friday, November 29, 2024
Google search engine
HomeLanguagesHow to handle app state without Redux ?

How to handle app state without Redux ?

In this article, we will learn about handling state without Redux. There are multiple ways to manage the state without redux in any web app. In this article, we will learn state management by useState() hook. It is a react hook that returns two values the state and a function by which we can mutate the state and we can initial state as arguments, in the code below it is an empty array. The component re-renders whenever the state changes. Let’s understand this with an example. In this web-app we will maintain the state ( which is the tasks array ) in the App component, pass down the tasks array to the Task component to display in a proper format and do the state mutation in the Tasks component with the help of function provided by useState() hook.

Syntax:

const [state,setState] = useState([]);

Creating React Application And Installing Module: 

Step 1: Create a React application using the following command.

npx create-react-app foldername

Step 2: After creating your project folder i.e. foldername, move to it using the following command:

cd foldername

Step 3: Run the development server by using the following command:

npm start

Project Structure: It will look like the following.

Implementation: Add the following code in respective files.

App.js : In this component we have created a state with the help of useState() and set its initial value to an array of only one element. Also we have passed down props to the Tasks component with their respective names.

Javascript




import { useState } from "react";
import "./App.css";
import Tasks from "./Component/Tasks";
  
function App() {
  const [taskList, setTaskList] = useState([
    {
      title: "Submit DS assignment",
      deadline: "1pm 10 March",
    },
  ]);
  
  return (
    <div className="App">
      <Tasks taskList={taskList} 
          setTaskList={setTaskList} />
    </div>
  );
}
  
export default App;


Tasks.js : In this component, we have added some basic styles and hooked up handleClick() and handleChange() to the button and input fields. We have used the method to dynamically update the object property via the syntax given below. This allows us to reduce the redundancy of creating different handleChange functions for different input fields. Also, note to use this method the input field has to have a name property on it. The handleClick() function is responsible for mutating the state and adding the current task to the App’s state. We have maintained a component state which is CurrentTask it will help us keep a track of the task that the user wants to add to the list.

Javascript




[e.target.name] : e.target.value


Javascript




import React, { useState } from "react";
import Task from "./Task";
  
const Tasks = ({ setTaskList, taskList }) => {
  const inputStyles = {
    border: "none",
    borderBottom: "2px solid #9FE6A0",
    outline: "none",
    margin: "10px",
  };
  
  const [CurrentTask, setCurrentTask] = useState({});
  
  let taskListDisplay = taskList.map((task, index) => {
    return (
      <Task
        key={index}
        index={index}
        deadline={task.deadline}
        title={task.title}
      />
    );
  });
  
  const handleClick = (e) => {
    setTaskList([...taskList, CurrentTask]);
  };
  
  const handleChange = (e) => {
    e.preventDefault();
    setCurrentTask({
      ...CurrentTask,
      [e.target.name]: e.target.value,
    });
  };
  
  return (
    <div>
      <h4>Task-Web-App :</h4>
      <div>
        <input
          style={inputStyles}
          placeholder="Title"
          type="text"
          value={CurrentTask.title !== undefined 
              ? CurrentTask.title : ""}
          name="title"
          onChange={handleChange}
        />
        <input
          style={inputStyles}
          placeholder="Deadline"
          type="text"
          value={CurrentTask.deadline !== undefined
              ? CurrentTask.deadline : ""}
          name="deadline"
          onChange={handleChange}
        />
        <button
          style={{
            outline: "none",
            border: "none",
            backgroundColor: "#9FE6A0",
            borderRadius: "8px",
            padding: "7px",
            width: "90px",
          }}
          onClick={handleClick}
        >
          Add Task
        </button>
      </div>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          flexDirection: "column",
        }}
      >
        {taskListDisplay}
      </div>
    </div>
  );
};
  
export default Tasks;


Task.js: This is just a presentational component that displays the task details by destructuring the values/properties.

Javascript




import React from "react";
  
const Task = ({ deadline, title, index }) => {
  return (
    <div
      style={{
        border: "2px solid #F55C47",
        width: "30vw",
        margin: "10px",
        borderRadius: "10px",
        padding: "8px",
      }}
    >
      <h2 style={{ margin: "2px", color: "#564A4A" }}>
          Task {index + 1} 
      </h2>
  
        
<p>
        {" "}
        <strong style={{ color: "#564A4A" }}> Title :</strong>
        <span style={{ color: "#707070" }}> {title}</span>
      </p>
  
        
<p>
        <strong style={{ color: "#564A4A" }}>Deadline : </strong>
        <span style={{ color: "#707070" }}>{deadline}</span>
      </p>
  
    </div>
  );
};
  
export default Task;


Working demo of the web-app:

Example 2: In this example, we will not maintain state in the App component but rather in some other child component, it will be Songs component. We will create two states one to store the singer’s name and the second will be the array of top 5 hit songs of the singer whose name the user has entered. And we’ll be fetching data from Rapid API’s open API this will be done with the help of axios. Implementation is discussed below.

Install the axios as a dependency:

npm i axios

Filename – App.js : Since we are not maintaining app state in this component we don’t need any state in this file.

Javascript




import { useState } from "react";
import "./App.css";
import Songs from "./Component/Songs";
import Tasks from "./Component/Tasks";
  
function App() {
  return (
    <div className="App">
      <Songs />
    </div>
  );
}
  
export default App;


Filename – Songs.js: In this Component, we have initialized the Singer’s name to be Justin by default which means it will fetch data for Justin on the initial render. We have made a fetchData function which is responsible for fetching data and updating the Songs component HitsSongs state, this function is initially called when the app loads to fetch the hit songs of Justin with the help of useEffect hook. Note the params object is what will hold the singer’s name while fetching the hit songs for the singer. We can reuse this fetchData function when the user clicks on the Find button because it is a stand-alone function and does make use of any other data except for updating the HitSongs state. And finally, we have hooked-up the onClick and onChange handlers to the button and input.

Javascript




import React, { useState,useEffect } from "react";
import axios from "axios";
  
const Songs = () => {
  const [HitSongs, setHitSongs] = useState([]);
  const [SingerName, setSingerName] = useState("Justin");
  
  const inputStyles = {
    border: "none",
    borderBottom: "2px solid #9FE6A0",
    outline: "none",
    margin: "10px",
  };
  
  const fetchData = async () => {
    var options = {
      method: "GET",
      params: { q: `${SingerName}` },
      headers: {
        "x-rapidapi-host": "genius.p.rapidapi.com",
        "x-rapidapi-key": "ffc2438edbmsh0a88b634e6e77a7p123125jsnfb163d4d72f7",
      },
    };
    let data = await axios.request(options);
    data = data.data.response.hits.slice(0, 5);
    setHitSongs(data);
  };
  
  const handleClick = (e) => {
    fetchData();
  };
  
  const handleChange = (e) => {
    e.preventDefault();
    setSingerName(e.target.value);
  };
  
  useEffect(() => {
    fetchData();
  }, []);
  
  let displaySongs = HitSongs.map((song) => {
    return (
      <div key={song.result.id}>
        <div
          style={{
            border: "2px solid #9FE6A0",
            width: "30vw",
            padding: "5px",
            margin: "8px",
          }}
        >
          {song.result.full_title}
        </div>
      </div>
    );
  });
  return (
    <>
      <div>
        <h4>Top 5 Hit songs :</h4>
        <div>
          <input
            style={inputStyles}
            placeholder="Singer Name"
            type="text"
            value={SingerName !== "" ? SingerName : ""}
            onChange={handleChange}
          />
  
          <button
            style={{
              outline: "none",
              border: "none",
              backgroundColor: "#9FE6A0",
              borderRadius: "8px",
              padding: "7px",
              width: "90px",
            }}
            onClick={handleClick}
          >
            Search
          </button>
        </div>
        <div
          style={{
            display: "flex",
            alignItems: "center",
            flexDirection: "column",
          }}
        ></div>
      </div>
      <div>
        {displaySongs.length === 0 ? (
          <>
            <div> Fetching data ... Please wait 🙂 </div>
          </>
        ) : (
          <div
            style={{
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
            }}
          >
            {displaySongs}
          </div>
        )}
      </div>
    </>
  );
};
  
export default Songs;


Working demo of the web-app:

Whether you’re preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape, neveropen Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we’ve already empowered, and we’re here to do the same for you. Don’t miss out – check it out now!

RELATED ARTICLES

Most Popular

Recent Comments