question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onChange + onClick event not batched into same render commit

See original GitHub issue

Reproduction

https://codesandbox.io/s/preact-setstate-overwrite-input-moy82

Steps to reproduce

(using preact/compat)

function App() {
  console.log("rerender");
  let [checked, setChecked] = React.useState(false);

  let [, setState] = React.useState(false);
  return (
    <>
      <input
        type="checkbox"
        checked={checked}
        onChange={(e) => {
          console.log("onChange", e.target.checked);
          setChecked(e.target.checked);
        }}
        onClick={(e) => {
          console.log("onClick", e.target.checked);
          // ... or uncomment calls to fix
          setState(true);
          setState(false);
        }}
      />
      <br />
      Checked? {String(checked)}
    </>
  );
}
  1. Try to toggle checkbox, doesn’t work because this happens:
onClick  true
rerender 
onChange  false

So the click was overwritten by the setState call

  1. With React:
onClick  true
onChange  true
rerender 
  1. Without the setState calls, it obviously works

Expected Behavior

The checkbox should toggle?

Not sure if this is something that can be fixed on the Preact side or if I need to add a workaround.

Actual Behavior

Nothing happens when clicking the checkbox.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
marvinhagemeistercommented, Sep 8, 2020

We do batch all state updates which is why the onClick handler only causes one re-render. But having a closer look it seems like our window is smaller compared to React. A quick workaround would be to enlarge the time where updates are batched:

import { options } from "preact";

options.debounceRendering = setTimeout;
1reaction
mischniccommented, Sep 8, 2020

Thanks, though I’m not comfortable adding this line in a UI component library 😅

Read more comments on GitHub >

github_iconTop Results From Across the Web

onclick event not triggered when onchange triggered right ...
I typed in a text into the textarea. Right after typing i click on the button to trigger the onclick event on the...
Read more >
Fix the slow render before you fix the re-render - Kent C. Dodds
Every time you click on the button, the Foo function is called, but the DOM that it represents is not re-rendered.
Read more >
Data Grid - Events - MUI X
You can subscribe to one of the events emitted by providing an event handler to the grid. The handler is a method that...
Read more >
Documentation - SolidJS · Reactive Javascript Library
The first execution of the effect function is not immediate; it's scheduled to run after the current rendering phase (e.g., after calling the...
Read more >
Working with React Form and Handling Event | Ibaslogic
React is telling us to add an onChange handler to keep track of any changes in the field. Else, it wouldn't know if...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found