Home > database >  React with uniqid not generating id
React with uniqid not generating id

Time:12-04

I'm making a todo list for my first react project. I'm using the uniqid generator for my todo object, but the way I currently have it set up is returning an id of '' instead of a random id. It seems to work if I set the todo state outside of the handleSubmit function, but I don't understand why it won't work as I have it now. I would truly appreciate any guidance on what I may be missing that's causing this problem. Thanks!

import { useState } from 'react';
import Header from './components/Header';
import List from './components/List';
import React from 'react';
import uniqid from 'uniqid';

function App() {
const [todoList, setTodoList] = useState([]);
const [todo, setTodo] = useState({
name: '',
complete: false,
id: ''
});
const [error, setError] = useState(false);

function handleChange(e) {
setTodo({
  ...todo,
    name: e.target.value,
});
}

function handleAdd(newTodo) {
setTodoList([
  ...todoList,
     newTodo
])
}

function handleSubmit(e) {
e.preventDefault();
if (!todo.name) {
  setError(true);
} else {    
  handleAdd({
    ...todo,
       id: uniqid()
  })
setError(false);
setTodo({
  ...todo,
     name: ''
})
console.log(todo);
}
}

function handleDelete(id) {
const todoListItems = todoList.filter(todo => todo.id !== id);
setTodoList(todoListItems);
}

function handleClear() {
setTodoList([]);
}

CodePudding user response:

The use of uniqid() seems to be correct, it is just that setTodo will update the value of todo in the next render of the component, but the following console.log(todo) in the same event block still only have the old value before the update.

A live example showing the unique ID generated: stackblitz

The above example also changed handleChange and handleAdd to the following format, so that the previous value can be used without potential conflicts.

function handleChange(e) {
  setTodo((prev) => {
    return { ...prev, name: e.target.value };
  });
}

function handleAdd(newTodo) {
  setTodoList((prev) => [...prev, newTodo]);
}

Also added a useRef to empty the input after submit, because the original implement cleaned the state value as "", but did not seems to do the same for input.

import { useRef } from 'react';

function handleSubmit(e) {
  e.preventDefault();

  ...

  setTodo((prev) => {
    return { ...prev, name: "" };
  });
  newTodoRef.current.value = "";
}

Hope this will help.

  • Related