Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Toggle state taking previous value in react?

I am trying to create a to-do list app. The basic functionality includes adding and deleting. So when a user selects one or multiple items, a delete button will appear and it will be deleted. My problem is I am implementing a toggle state which when a user clicks on todo item, it will be strikethrough( A strikethrough text decoration will be added via CSS).
The problem arises when I add two items. When I click on the first item , it gets a strike through and when I delete it, the first one goes but the second item gets the strike through this time.

The running sample in codesandbox. Just try adding two items and delete the first one. The second one also gets a strike through.

I believe its because the toggle state value is being remembered.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is the Content.js component

import "./styles/content.css";
import Individual from "./Individual";
import { useEffect, useState } from "react";
import { updateItem, markIncomplete } from "./action/action";
const Contents = (props) => {
  const items = useSelector((state) => state.todoReducer.items);

  const dispatch = useDispatch();
  const handleClick = (e, isComplete, content, id) => {
    // console.log(isComplete);

    if (isComplete === false) {
      //evaluates false to true
      const newobj = {
        isComplete: true,
        content,
        id
      };

      dispatch(updateItem(newobj));

      props.deletebutton(true);
    } else {
      const falseobj = {
        isComplete: false,
        content,
        id
      };

      dispatch(markIncomplete(falseobj));
    }
  };


  useEffect(() => {
    console.log("statechanging of contents");
  });
  return (
    <div className="content-ui">
      <div>
        {items.map((vals) => (
          <Individual
            vals={vals}
            deletebutton={props.deletebutton}
            handleClick={handleClick}
          />
        ))}
      </div>
    </div>
  );
};

export default Contents;

This is the individual.js which deals with toggle function

import { useDispatch, useSelector } from "react-redux";
import "./styles/content.css";
import { updateItem, markIncomplete } from "./action/action";
const Individual = (props) => {
  console.log("child" + props.vals.isComplete);
  const [toggle, isToggled] = useState(false);
  const handleToggle = () => {
    const mytoggle = !toggle;
    isToggled(mytoggle);
  };
  return (
    <div>
      <div
        className={toggle ? "toggled" : "card-elements"}
        onMouseDown={handleToggle}
        onClick={(e) => {
          props.handleClick(
            e,
            props.vals.isComplete,
            props.vals.content,
            props.vals.id
          );
          handleToggle;
        }}
      >
        {props.vals.content}
      </div>
    </div>
  );
};
export default Individual;

Css of toggler

.toggled {
  /* border: 1px solid rgb(94, 94, 94); */
  box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
  text-align: left;
  box-sizing: border-box;
  padding: 10px 3px 10px 7px;
  margin-top: 4px;
  margin-bottom: 8px;
  border-radius: 5px;
  background-color: white;
  font-size: 12px;
  font-family: "Roboto ", monospace;
  text-decoration: line-through;
}
.card-elements {
  /* border: 1px solid rgb(94, 94, 94); */
  box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
  text-align: left;
  box-sizing: border-box;
  padding: 10px 3px 10px 7px;
  margin-top: 4px;
  margin-bottom: 8px;
  border-radius: 5px;
  background-color: white;
  font-size: 12px;
  font-family: "Roboto ", monospace;
}


>Solution :

You need to add keys to your mapped items (there should also be a warning about this in the console).

Keys help React identify which items have changed, are added, or are removed.

As is stated from React’s documents.

return (
    <div className="content-ui">
      <div>
        {items.map((vals) => (
          <Individual
            key={vals.id} // <-- add unique key
            vals={vals}
            deletebutton={props.deletebutton}
            handleClick={handleClick}
          />
        ))}
      </div>
    </div>
  );
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading