简体   繁体   中英

react does not re-render on state change

I have this functional component:

const PriorityInput = () => {
  const [isActive, setIsActive] = useState({
    taskPriorityLow: false,
    taskPriorityMedium: false
  });

  const onPriorityClick = name => {
    Object.keys(isActive).forEach(key =>
      key === name ? setIsActive({ ...isActive, [key]: true }) : setIsActive({ ...isActive, [key]: false })
    );
  };

  return (
     <div className="task-priority-input-container">
        <label className="task-priority-input-label">Priority</label>
        <span
          className={
            isActive.taskPriorityLow
              ? "task-priority-button task-priority-low-active"
              : "task-priority-button task-priority-low"
          }
          onClick={() => onPriorityClick("taskPriorityLow")}
        >
          LOW
        </span>
<span
          className={
            isActive.taskPriorityLow
              ? "task-priority-button task-priority-medium-active"
              : "task-priority-button task-priority-medium"
          }
          onClick={() => onPriorityClick("taskPriorityMedium")}
        >
          MEDIUM
        </span>
      </div>
  );
};

export default TaskForm;

however when I click on the span its style does not change.

From similar questions I understood that calling setIsActive() with spread object would trigger a rerender.

Jan. I think it's not necessary foreach statement.

trying to do like this.

 const PriorityInput = () => { const [isActive, setIsActive] = React.useState({ taskPriorityLow: false, taskPriorityMedium: false, taskPriorityHigh: false, }); const onPriorityClick = name => { console.log("clicked - ", name); const updateActive = {...isActive}; Object.keys(isActive).forEach(key => { if(key === name) updateActive[key] = true; else updateActive[key] = false; }); setIsActive(updateActive); }; return ( <div className="container"> <label className="input-label">Priority</label> <span className={ isActive.taskPriorityLow ? "btn btn-primary" : "btn btn-secondary" } onClick={() => onPriorityClick("taskPriorityLow")} > LOW </span> <span className={ isActive.taskPriorityMedium ? "btn btn-primary" : "btn btn-secondary" } onClick={() => onPriorityClick("taskPriorityMedium")} > MEDIUM </span> <span className={ isActive.taskPriorityHigh ? "btn btn-primary" : "btn btn-secondary" } onClick={() => onPriorityClick("taskPriorityHigh")} > HIGH </span> </div> ); }; const rootElement = document.getElementById("root"); ReactDOM.render(<PriorityInput />, rootElement);
 <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.2/umd/react-dom.production.min.js"></script> <div id="root"></div>

instead of this

Object.keys(isActive).forEach(key =>
  key === name ? setIsActive({ ...isActive, [key]: true }) : setIsActive({ ...isActive, [key]: false })
);

directly you can write

setIsActive({ ...isActive, [name]: true }) 

this should help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM