Home > Back-end >  Change each individual element style based on condition
Change each individual element style based on condition

Time:12-25

I am trying to change the background color of select element based on which option user selects. I have created this example https://codepen.io/lordKappa/pen/YzrEWXd and here the color changes but it also changes for all select elements not just for the one we changed.

  const [selectState, setSelectState] = useState("To-do");
  const [taskID, setTaskID] = useState();

  function handleDropdownChange(e) {
    var taskID = e.currentTarget.getAttribute("data-index");
    setTaskID(taskID);
    setSelectState(e.target.value);
  }

  if (selectState === "To-do") {
    selectStyle = {
      backgroundColor: "red",
    };
  } else if (selectState === "Done") {
    selectStyle = {
      backgroundColor: "green",
    };
  } else {
    selectStyle = {
      backgroundColor: "yellow",
    };
  }

  return (
    <div className="box">
      <div>
        {elementList.map((task) => (
          <div key={task.id}>
            <h1>{task.info}</h1>
            <select
              onChange={handleDropdownChange}
              data-index={task.id}
              style={selectStyle}
            >
              <option value="To-do">To-do</option>
              <option value="Done">Done</option>
              <option value="In progress">In progress</option>
            </select>
          </div>
        ))}
      </div>
    </div>
  );
};

CodePudding user response:

The color changes an all dropdowns in the code-pen you provided because they all rely on the same piece of state. You either need to make the state for each dropdown be independent of each other, or separate the dropdown into its own component.

CodePudding user response:

You should create a state for tasks

  const [tasks, setTasks] = useState([
   { id: 0, info: "Task 1", status: 'TODO' },
   { id: 1, info: "Task 2", status: 'TODO' },
   { id: 2, info: "Task 3", status: 'TODO' }
  ]);

Then, everytime you change the selectbox, update status inside tasks state

function handleDropdownChange(e) {
    var taskID = e.currentTarget.getAttribute("data-index");
    setTasks(tasks.map(task => {
     if (taskID !== task.id) return task;
     task.status = e.target.value
     return task
    }));
  }

Finally, when rendering tasks we only need to check the task's status and change style

{elementList.map((task) => {
// put your condition here ....
return (
          <div key={task.id}>
            <h1>{task.info}</h1>
            <select
              onChange={handleDropdownChange}
              data-index={task.id}
              style={selectStyle}
            >
              <option value="To-do">To-do</option>
              <option value="Done">Done</option>
              <option value="In progress">In progress</option>
            </select>
          </div>
        )
})}
  • Related