Home > database >  React - to do list - State only re rendering on page refresh
React - to do list - State only re rendering on page refresh

Time:08-28

Update: {SOLVED} --> state was not updating as the tasks state was containing object arrays retrieved from db, whereas when updating state directly using setTasks([...tasks,input]) was causing the last state to be a string value. Updated my post method to return the new item , which when used to update state worked.

I am new to React. I am using hooks to update my state but the added new task only reflects upon page refresh. Not able to understand what is going on wrong here. And If i put the state variable in the useEffect dependency array , then it leads to infinite re renders. I have tried numerous solutions but nothing seems to work

on submit: enter image description here on refresh : enter image description here

import React,{useState,useEffect} from "react";
import './App.css';

function App() {

  const URL = "http://localhost:5000";

  const [input,setInput] = useState("");
  const [tasks , setTasks] = useState([]);

  useEffect(()=>{
    fetchedItems().then(res=>{
    console.log(res);
    setTasks(res);
    })
  },[])

  const fetchedItems = ()=>{
    return fetch(URL)
    .then(res=>res.json());
  }

  function handleInputChange(e){
    setInput(e.target.value);
  }

  async function handleSubmit(e){
    e.preventDefault();
    const originalTasks = tasks;
    try{
      const results = await fetch(URL,{
        method:"POST",
        headers:{"content-Type":"application/json"},
        body:JSON.stringify({input:input})
      });
      originalTasks.push(input);
      setInput("");
      setTasks(originalTasks);
    }
    catch(err){
      console.log("error:",err)
    }
  }

  return(
  <div>
    <div>
      <h2>To Do List</h2>
    </div>
    <form onSubmit={handleSubmit}>
      <input name="input" type="text" placeholder="enter task" value={input} onChange={handleInputChange}></input>
      <button type="submit">Add Task</button>
    </form>
    <ul>
    {tasks.map((task)=>
      <li key={task._id} id={task._id}>{task.value}</li>
    )}
    </ul>
  </div>
  );
}

export default App;

my app.js file that i am using as backend :

const express = require("express");
const bodyParser = require("body-parser");
const todolistRoute = require("./Routes/todolistRoute");
const mongoose = require("mongoose");
require("dotenv/config");
const cors = require('cors');
const listModel = require("./Models/listModel");

const app = express();

//Midlewares
app.use(cors());
app.use(bodyParser.json());
app.use(express.json());
// app.use('/todolist',todolistRoute);

//connect to MongoDB
mongoose.connect(process.env.DB_CONNECTION, ()=>{
  console.log("connected to TodoList DB");
})

//Routes
app.get("/",async (req,res)=>{
  try{
    const fetchedItems = await listModel.find();
    res.json(fetchedItems);
    console.log("get request was made to server to fetch items")
  }
  catch(err){
    console.log(err);
  }
})

.post("/", async (req,res)=>{ // should add a new todo item
  try{
    console.log(req.body.input);
    const item = new listModel({
      value:req.body.input
    });
    console.log(`item ID ${item.id} stored in DB`);
    await item.save();
  }
  catch(err){
    console.log(err);
  }
});


//listen on port
const port = 5000
app.listen(port, ()=>{
  console.log(`listening on port ${port}`);
})

CodePudding user response:

import React,{useState,useEffect} from "react";
import './App.css';

function App() {

  const URL = "http://localhost:5000";

  const [input,setInput] = useState("");
  const [tasks , setTasks] = useState([]);
  const [refresh,setRefresh] = useState(false);

  useEffect(()=>{
    fetchedItems().then(res=>{
    console.log(res);
    setTasks(res);
    })
  },[refresh])

  const fetchedItems = ()=>{
    return fetch(URL)
    .then(res=>res.json());
  }

  function handleInputChange(e){
    setInput(e.target.value);
  }

  async function handleSubmit(e){
    e.preventDefault();
    
    try{
      const results = await fetch(URL,{
        method:"POST",
        headers:{"content-Type":"application/json"},
        body:JSON.stringify({input:input})
      });
      
      setInput("");
      setRefresh((prev)=>!prev)
    }
    catch(err){
      console.log("error:",err)
    }
  }

  return(
  <div>
    <div>
      <h2>To Do List</h2>
    </div>
    <form onSubmit={handleSubmit}>
      <input name="input" type="text" placeholder="enter task" value={input} 
      onChange={handleInputChange}></input>
      <button type="submit">Add Task</button>
    </form>
    <ul>
    {tasks.map((task)=>
      <li key={task._id} id={task._id}>{task.value}</li>
    )}
    </ul>
  </div>
  );
}

export default App;

CodePudding user response:

Update: {SOLVED} --> state was not updating as the tasks state was containing object arrays retrieved from db, whereas when updating state directly using setTasks([...tasks,input]) was causing the last state to be a string value. Updated my post method to return the new item , which when used to update state worked

  • Related