Home > database >  why does react js renders two times when setting a state
why does react js renders two times when setting a state

Time:10-23

I have this code that uses useState to make a form appear or disapear when clicking a button

    const [searchClick, setSearchClick] = useState("hidden")

         // Button when clicked the form appears or disappears
        <label onClick={() => setSearchClick(prevState => prevState ==='hidden' ? 'flex' : 'hidden') } className="btn-xs btn-ghost rounded-full w-fit h-fit swap swap-rotate" >
            <input  type="checkbox" />
            <Search className="swap-off relative right-1" width="22px" height="22px" fill='#8DD0BA' />
            <svg className="swap-on fill-current" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 512 512"><polygon points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49"/></svg>
        </label>

        <form className={`${searchClick} my-6 justify-center`}>
            <input type="text" placeholder="Search" className="input input-bordered max-w-lg bg-white text-black" />
            <button className="btn w-18 rounded-r-none"><Search /></button>
        </form>

when I'm putting the onclick function in the label tag it causing two renders and it's not working well but when I'm putting it in the input tag it's working well

CodePudding user response:

The problem is not in React rendering, but in handling label clicks. Your handling function is first triggered from label or its children svg or polygon (causing render) and then from input (another render). It can be logged and debugged like this with event.target:

function YourComponent() {
  const [searchClick, setSearchClick] = useState("hidden");

  const onClickFnc = (event) => {
    console.log("onClick called", event.target);
    setSearchClick((prevState) => (prevState === "hidden" ? "flex" : "hidden"));
  };

  console.log("rendering component");

  return (
    <div>
      <label
        onClick={onClickFnc}
        className="btn-xs btn-ghost rounded-full w-fit h-fit swap swap-rotate"
      >
        <input type="checkbox" />
        <svg
          className="swap-on fill-current"
          xmlns="http://www.w3.org/2000/svg"
          width="32"
          height="32"
          viewBox="0 0 512 512"
        >
          <polygon points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49" />
        </svg>
      </label>
      <div>Current state: {searchClick}</div>
    </div>
  );
}

It can be solved by adding handler on input and some event.stopPropagation(), nice example here: https://stackoverflow.com/a/38958110/5940854

  • Related