Home > OS >  if(state){useState} delay by one Event
if(state){useState} delay by one Event

Time:08-24

this is, what I want: I click on the div as a checkbox, and if it's clicked, the NEXT-Button should be enabled. But with if (checkboxClass === "checkbox-clicked") the update comes one click later.

I click on the check: nothings happend, I uncheck: the button is enabled.

how can i get an instand update ?


import React, { useState } from "react";

import "../css/MainPages.css";
import "../css/Request.css";

function Test() {
  const [checkboxClass, setClassName] = useState("checkbox");
  const [buttonState, setButtonState] = useState(true);

  function handleClass() {
    if (checkboxClass == "checkbox") {
      setClassName("checkbox-clicked");
    }
    checkButton();
  }

  function checkButton() {
    if (checkboxClass === "checkbox-clicked") {
      setButtonState(false);
    }
  }

  return (
    <>
      <div onClick={handleClass} className={checkboxClass} />

      <button disabled={buttonState} className="btn btn-transparent">
        Next
      </button>
    </>
  );
}
export default Test;

CodePudding user response:

Yes, It's because setButtonState is not executed immediately. You must think, that setState is request to change the value and react by self will decides when it will be executed.

Your checkButton() method is immediately after setState, therefore when checkButton method is executes, that state is still not changed (but will change, few miliseconds later).

To solve you situation, you can use useEffect react hook, which will be listening on checkbox state change, and when state will be changed, useEffect will by automaticaly executed:

// Second parameter is, to which states will be useEffect listening
useEffect(() => { checkButton(); }, [checkboxClass])

CodePudding user response:

You're using derived state, which generally leads to unexpected behaviors. You can (and imo you should) disable the button based on the checkboxClass state variable:


import React, { useState } from "react";

import "../css/MainPages.css";
import "../css/Request.css";

function Test() {
  const [checkboxClass, setClassName] = useState("checkbox");

  const isButtonDisabled = checkboxClass === "checkbox-clicked"

  function toggleCheckboxClass() {
    setClassName(prevClassName => prevClassName === "checkbox" ?
       "checkbox-clicked" : "checkbox")
  }

  return (
    <>
      <div onClick={toggleCheckboxClass} className={checkboxClass} />

      <button disabled={isButtonDisabled} className="btn btn-transparent">
        Next
      </button>
    </>
  );
}
export default Test;

Another opinion:

I would not use a div if you are actually rendering a checkbox and set the state variable based on e.target.checked since it is not semantically correct.

  • Related