Home > front end >  getting waring in console and my display list function/component is not working
getting waring in console and my display list function/component is not working

Time:11-02

i am making a simple to do list, yet in that there is some error on remove button and its action, if i dont add any function regarding remove list, everything is working fine...

here is my code:

ToDo.js

import React, { useState } from 'react'
import AddNew from './Addnew';
import ToDoList from './ToDoList';

function Todo() {

    const[toDoList, setToDoList] = useState([]);

    function addNew(addText, date){
        // console.log(addText);
        // console.log(date);
        const obj = {
            text : addText,
            expiry : date,
            completed : false
        }
        const newToDo = [...toDoList, obj];
        setToDoList(newToDo); 
        // console.log(toDoList);
    }

    function handleCheck(index){
        const newToDOs = [...toDoList];
        if(toDoList[index].completed==false){
            newToDOs[index].completed = true;
        }
        else {
            newToDOs[index].completed = false;
        }
        setToDoList(newToDOs);
    }

    function RemoveList(index){
        console.log(index);
        const newTo = [...toDoList];
        newTo.splice(index,1);
        setToDoList(newTo);
    }

    return ( 
        <>
            <h1>To Do List</h1>
            <AddNew addNew={addNew}/>
            <ul className="list-group">
            <ToDoList list={toDoList} handleCheck={handleCheck} RemoveList={RemoveList} />
            </ul>
        </>
     );
}

export default Todo;

ToDoList.js

import React from "react";

function ToDoList(props) {
  return (
    <>
      {/* {props.list.length == 0 ? <h3>To Do List is Empty</h3> : null} */}
      {props.list.map((element, index) => {
        return (
          <>
            <li
              className={
                element.completed
                  ? "list-group-item yes-comp"
                  : "list-group-item no-comp"
              }
            >
              <span className="badge text-bg-info">{index   1}</span> &ensp;
              <input
                type="checkbox"
                defaultChecked={element.completed}
                onChange={() => {
                  props.handleCheck(index);
                }}
              />{" "}
              &ensp;
              {element.text}
              <span className="badge text-bg-light">
                {element.expiry.toString().slice(4, 15)}
              </span>
              <button className="btn btn-danger" onChange={props.RemoveList(index)} >Remove</button>
            </li>
          </>
        );
      })}
    </>
  );
}

export default ToDoList;

AddNew.js

import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

function AddNew(props) {
  const [startDate, setStartDate] = useState(new Date());
  const [input, setInput] = useState("");

  function submitData() {
    props.addNew(input, startDate);
    setInput("");
  }

  return (
    <>
      <div className="Container InputContain">
        <input className="form-control" placeholder="Add New in To Do List" value={input} onInput={(e) => setInput(e.target.value)} />
        <div>
        <DatePicker
            className="AddDate"
          selected={startDate}
          onChange={(date) => setStartDate(date)}
        />
        <button className="btn btn-primary btn-cust" onClick={submitData}>Add</button>
      </div>
      </div>
    </>
  );
}

export default AddNew;

the warnings are:

react-dom.development.js:86 Warning: Cannot update a component (`Todo`) while rendering a different component (`ToDoList`). To locate the bad setState() call inside `ToDoList`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at ToDoList (http://localhost:3000/static/js/bundle.js:262:21)
    at ul
    at Todo (http://localhost:3000/static/js/bundle.js:374:82)
    at App

react-jsx-dev-runtime.development.js:87 Warning: Each child in a list should have a unique "key" prop.

Check the render method of `ToDoList`. See https://reactjs.org/link/warning-keys for more information.
    at ToDoList (http://localhost:3000/static/js/bundle.js:262:21)
    at ul
    at Todo (http://localhost:3000/static/js/bundle.js:374:82)
    at App

i tried to change my function name, change method on how to remove from list and everything that i could find on google, yet not working!

CodePudding user response:

Without running the code, I believe your issue is this line of code:

<button className="btn btn-danger" onChange={props.RemoveList(index)} >Remove</button>

Event handlers should always be passed a call-back function to be stored in memory for when the event happens. Also, this event handler should be an onClick. Your onClick atribute should look like this:

onClick={() => props.RemoveList(index)}

As a side note, passing a function call to an event handler only works if the function being called returns a function itself and has no side-effects:

const getCallback = () => {
  const callback = () => setState('foo');

  return callback;
}
<button onClick={GetCallback()}> set state </button>

Hope this helps.

CodePudding user response:

You'll want to fire the remove function from onClick(), not onChange(). Another thing is, that when you pass the reference to the onClick, such as onClick={props.RemoveList(index)}, the onClick event calls the removeList() function with HTMLEvent as a parameter.

To fix your code, simply change the remove button from:

<button className="btn btn-danger" onChange={props.RemoveList(index)} >Remove</button>

to

<button className="btn btn-danger" onClick={() => props.RemoveList(index)}>Remove</button>.

As a note, using index as a key to remove things from a list is a bad idea. Consider generating unique ID for each todo, and use that to identify the correct todo.

CodePudding user response:

You are calling the method directly, not passing a reference to it. also there isnt onChange for button So

onChange={props.RemoveList(index)}

should be changed to

onClick={() => props.RemoveList(index)}

Also regarding the second waring, add a key attribute to your li tag

        <li
          className={
            element.completed
              ? "list-group-item yes-comp"
              : "list-group-item no-comp"
          }
          key={element.text}
        >

Indexes are not best practice to be used as key values, so i added the text property here, but you should use something more "unique", which also should be used at your RemoveList function.

  • Related