skip to Main Content

I have one simple question. In my ToDo list app, creating by React, i have many requests to the server (at list 4 requests with a different methods – GET, POST, PATCH, DELETE), where i should write they ? If i did it in one useEffect, i guess i will need use conditions if{} in it. Does its right approach to build apps on React with CRUD operations ?

My app:

import {useEffect, useState} from "react";

function MainList() {
  const [newTask, setNewTask] = useState('');
  const [profile, setProfile] = useState([])
  const [toDo, setToDo] = useState([])
  const [taskAdd, setTaskAdd] = useState(false)

  useEffect(() => {
    if (taskAdd) {
      fetch('/server/someId', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({...profile, list: toDo})
      }).then(res => setTaskAdd(false))
    } else {
      fetch('/server/someId')
        .then(res => {
          const currentAccount = res.find(el => el.status);         
          // Here we take our current account, where store all it
          // tasks. Response from the server will be array of object's(accounts), 
          // and when user login(from previous
          // login page), we change in his account (object) key - 'status' from false to true, 
          // for understanding who
          // exactly was login and take his data to work with.
          setProfile(currentAccount);
          setToDo(currentAccount.list);
        })
    }

  }, [taskAdd])


  const suby = (event) => {
    event.preventDefault()
    const goal = {
      id: Math.floor(Math.random() * 1000) + 1 + '',
      task: newTask
    }
    setToDo([...toDo, goal])
    setTaskAdd(true)
  }
  return (
    <div>
      <h1>ToDo List</h1>
      <form onSubmit={suby}>
        <label>
          <input
            type="text"
            onChange={(event) => setNewTask(event.target.value)}
            value={newTask}
          />
        </label>
        <button type="submit">Add task</button>
      </form>
      <ul>
        {toDo.map(el => <li key={el.id}>{el.task}</li>)}
      </ul>
    </div>
  )
}

export default MainList;

2

Answers


  1. I think you are just have some concerns of using useEffect.

    This all depends on when you want to call the API, most of time, people want to invoke the API after the mount, so useEffect can help to invoke them. But if you decide to invoke it upon a mouse click etc, then you most likely wire it with a onClick handler. So useEffect isn’t the only place.

    Whether you can put one or two api calls inside one useEffect or two, that’s really up to you, because all useEffect calls are stacked and bundled to be invoked after the current DOM render, so if you have two useEffect (even inside two different components), they will be all invoked one after another one.

    Login or Signup to reply.
  2. you can make custom hooks for data fetching by passing API URL as function parameter.

        //hook
    
        import { useState, useEffect } from 'react';
    
        function useFetch(url) {
          const [data, setData] = useState(null);
          const [isLoading, setIsLoading] = useState(true);
          const [error, setError] = useState(null);
        
          useEffect(() => {
            const fetchData = async () => {
              try {
                const response = await fetch(url);
                if (!response.ok) {
                  throw new Error('Network response was not ok');
                }
                const data = await response.json();
                setData(data);
              } catch (error) {
                setError(error);
              } finally {
                setIsLoading(false);
              }
            };
        
            fetchData();
          }, [url]);
        
          return { data, isLoading, error };
    
    }
    
    /// component
    
    
    
    function MyComponent() {
          const url="any"
          const { data, isLoading, error } = useFetch(url);
        
          if (isLoading) {
            return <p>Loading...</p>;
          }
        
          if (error) {
            return <p>Error: {error.message}</p>;
          }
        
          return (
            <div>
              <h1>Data</h1>
              <pre>{JSON.stringify(data, null, 2)}</pre>
            </div>
          );
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search