primitives icon indicating copy to clipboard operation
primitives copied to clipboard

[bug]: Checkbox in a form with onClick on parent causes infinite state update

Open Spoof14 opened this issue 1 year ago • 6 comments
trafficstars

Bug report

Current Behavior

With the simple example of

function App() {
  const [isChecked, setIsChecked] = useState(false);

  return (
      <form>
        <div onClick={() => setIsChecked((prev) => !prev)}>
          <Checkbox checked={isChecked} />
          <span>test</span>
        </div>
      </form>
  )
}

The app crashed due to infinite state updates. Stopping propogation does nothing.

Expected behavior

The checkbox goes from unchecked to checked

Reproducible example

CodeSandbox Template

Suggested solution

Stop firing onClick multiple times. Perhaps make the checkbox into an actual <input type='checkbox'>

Your environment

Software Name(s) Version
Radix Package(s) checkbox 1.1.2
React n/a 18.3
Browser chrome 130
Assistive tech
Node n/a
npm/yarn
Operating System windows 11

Spoof14 avatar Oct 24 '24 07:10 Spoof14

Relates to #https://github.com/radix-ui/primitives/issues/2549#issuecomment-2070021911

Spoof14 avatar Oct 24 '24 07:10 Spoof14

Same here, really annoying

CarlosVergikosk avatar Oct 25 '24 14:10 CarlosVergikosk

Same here!

andersonba avatar Nov 27 '24 20:11 andersonba

I found a workaround by wrapping the Checkbox.Root component with memo. See in CodeSandbox

andersonba avatar Nov 27 '24 20:11 andersonba

Found the same (?) bug in slightly different scenario : https://github.com/radix-ui/primitives/issues/3265

Tom-Aive avatar Dec 03 '24 14:12 Tom-Aive

Found a workaround with

onClick={(e) => {
  const target = e.target as HTMLElement;
  
  if (target.closest('input')) {
    return;
  }

  setIsChecked((prev) => !prev)
}}

andreivictor avatar May 23 '25 09:05 andreivictor

@andersonba This is the only solution that worked with me.

HasanMothaffar avatar Sep 09 '25 11:09 HasanMothaffar