skip to Main Content

I am trying to make a small app to learn react basics where I enter in random items and it lists them below. When I press the delete button for that item, it should delete it. The problem is that it is deleting all items that come after it as well.

I tried logging the state of item in various spots and realized that inside the function deleteHandler, the item state array was only full of the things that came before the item I was trying to delete for some reason. But when I log item outside of that function, it properly shows all items. Any ideas what the issue could be?

App.js

const App = () => {
    const [item, setItem] = useState([]);
    console.log(item);
    for (const i of item){
        console.log(i.props.id);
    }
    const [itemCount, setItemCount] = useState(0);
    const handleNewName = (newName) => {
        console.log("new name has been recieved: "+newName);
        setItem([...item, <ListItem itemName={newName} deleteHandler={deleteHandler} key={itemCount} id={itemCount} />]);
        setItemCount(currentCount => currentCount + 1);
        console.log(itemCount);
        
    }

    const deleteHandler = (key) => {
        setItem(item.filter(i=>i.props.id !== key));
    }
    return (
    <>
        <InputArea handleNewName={handleNewName}/>
        {item}
    </>
    );
}

export default App

inputArea.js

export default function InputArea(props){
  const [inputValue, setInputValue] = useState("");
  const handleNewName=props.handleNewName;
  let currName="";
  function snagName(){
    currName = inputValue;
    setInputValue("");
    handleNewName(currName);
  }
  return (
    <>
    <input value={inputValue} onChange={(e)=>setInputValue(e.target.value)}/>
    <button onClick={snagName}>Submit</button>
    <br/>
    </>
  );
}

listItem.js

export default function ListItem (props){
  let currName=props.itemName; 
  let id = props.id;
  const deleteHandler = props.deleteHandler;
  const clickHandler = () => deleteHandler(id);
  return (
    <>
    <button onClick={clickHandler}>Delete</button><span>Hello, {currName}</span><br/>
    </>
  )
}

2

Answers


  1. Chosen as BEST ANSWER

    I was able to fix the issue by adding

    const stateRef = useRef();
    stateRef.current=item;
    

    at the top of my code and changing deleteHandler to

    setItem(stateRef.current.filter(i=>i.props.id !== key));

    Is there no better way to solve this? It seems awfully roundabout and complicated for such a simple program compared to vanilla js. Is that just how react is?

    EDIT: Found a better way (I think). The problem appears to be solved just by changing from setItem(item.filter(i=>i.props.id !== key)); to setItem(currVal => currVal.filter(i=>i.props.id !== key));


  2. The issue in your code lies within the deleteHandler function. Specifically, in this line:

    setItem(item.filter(i=>i.props.id !== id));
    

    In the filter function, you’re using id as the parameter instead of key. Since id is not defined within the deleteHandler function, it is treated as undefined. As a result, the filter condition will always evaluate to true, causing all items to be filtered out.

    To fix this issue, you should replace id with key in the deleteHandler function. Here’s the corrected code:

    const deleteHandler = (key) => {
      setItem(item.filter(i => i.props.key !== key));
    }
    

    This change ensures that only the item with the matching key will be filtered out, while preserving the rest of the items.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search