Search code examples
htmlcssreactjsinline-styles

changing styles by id onClick in react only working once


I am trying to change styles on each list item for each task added and it works... but only once. After clicking 'complete' it should cross out tasks and run the styles. The rest of the tasks are not working I am assuming because id should only belong to one element. How can I fix this? This is the html

 {tasks.map((x, key) => {
              return (
                <div className="task-list-item">
                  <ul>
                    <li className="li-title" id="title" key={key}>
                      {x.title}
                    </li>
                    <li className="li-desc" id="desc" key={key}>
                      {x.description}
                    </li>
                  </ul>
                  <div className="btn-container">
              <button onClick={handleStyleComplete} className="task-btns">
                      Complete
                    </button>
                    <button className="task-btn-del">Delete</button>
                  </div>
                </div>
              );

and this is the onClick function

 const handleStyleComplete = (e) => {
    document.getElementById("title").style.textDecoration = "line-through";
    document.getElementById("title").style.color = "grey";
    document.getElementById("desc").style.textDecoration = "line-through";
    document.getElementById("desc").style.color = "grey";
    e.target.style.backgroundColor = "transparent";
    e.target.style.cursor = "auto";
    e.target.style.border = "none";
    e.target.style.color = "transparent";
  };

I have tried using getElementByClassName.style, but this does not work.

Here is what it looks like https://i.sstatic.net/m5mfM.png


Solution

  • Rather than using document.getElementById, you could apply different styles to your element depending upon their state of your task where they are complete or not.

    For example :-

    const [tasks, setCompleteTasks] = React.useState([]);
    const handleStyleComplete = (id) => {
        // tell your state here, that these task is complete.
        setCompleteTasks([...tasks, id]);
      };
    
    {tasks.map((x, key) => {
                  // using this derived state you could apply styles here
                  const isCompleteTask = tasks.includes(x.id);
                  return (
                    <div className="task-list-item">
                      <ul>
                        <li className={isCompleteTask ? 'lineThroughStyles' : 'li-title'} id="title" key={key}>
                          {x.title}
                        </li>
                        <li className="li-desc" id="desc" key={key}>
                          {x.description}
                        </li>
                      </ul>
                      <div className="btn-container">
                  <button onClick={() => completeTasks(x.id)} className={isCompleteTask ? 'taskCompleteButtonStyles' : 'task-btns'}>
                          Complete
                        </button>
                        <button className="task-btn-del">Delete</button>
                      </div>
                    </div>
                  );