Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(restructure) - controlled components #3251

Merged
merged 7 commits into from
Aug 30, 2021

Conversation

JoviDeCroock
Copy link
Member

@JoviDeCroock JoviDeCroock commented Aug 23, 2021

This is a bit of a new feature a big nuisance in Preact X was that when people had components like this:

import { useState } from 'preact/hooks';

const Input = () => {
  const [value, setValue} = useState('');
  const onInput = e => {
    if (e.target.value.length > 3) return;
    setValue(e.target.value);
  }
  return <input value={value} onInput={onInput} />
}

This would transition to an uncontrolled component as the underlying dom-element would update to the new character but there was no trigger to the render cycle for this meaning that the control expressed in this event-handler wasn't respected.

@github-actions
Copy link

github-actions bot commented Aug 23, 2021

📊 Tachometer Benchmark Results

Summary

duration

  • 02_replace1k: unsure 🔍 -2% - +3% (-2.71ms - +5.25ms)
    preact-local vs preact-master
  • 03_update10th1k_x16: unsure 🔍 -1% - +3% (-0.77ms - +2.61ms)
    preact-local vs preact-master
  • 07_create10k: unsure 🔍 -3% - +1% (-41.10ms - +8.81ms)
    preact-local vs preact-master
  • filter_list: unsure 🔍 -1% - +3% (-2.12ms - +5.89ms)
    preact-local vs preact-master
  • hydrate1k: unsure 🔍 -2% - +2% (-1.84ms - +1.84ms)
    preact-local vs preact-master
  • many_updates: unsure 🔍 -2% - +2% (-2.02ms - +2.41ms)
    preact-local vs preact-master
  • text_update: unsure 🔍 -4% - +4% (-2.54ms - +2.68ms)
    preact-local vs preact-master
  • todo: unsure 🔍 -2% - +2% (-1.39ms - +1.10ms)
    preact-local vs preact-master

usedJSHeapSize

  • 02_replace1k: unsure 🔍 -0% - +0% (-0.00ms - +0.01ms)
    preact-local vs preact-master
  • 03_update10th1k_x16: unsure 🔍 -0% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-master
  • 07_create10k: unsure 🔍 +0% - +0% (+0.00ms - +0.00ms)
    preact-local vs preact-master
  • filter_list: unsure 🔍 -1% - +1% (-0.02ms - +0.02ms)
    preact-local vs preact-master
  • hydrate1k: unsure 🔍 -0% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-master
  • many_updates: unsure 🔍 -0% - +0% (-0.01ms - +0.00ms)
    preact-local vs preact-master
  • text_update: unsure 🔍 -2% - +3% (-0.02ms - +0.03ms)
    preact-local vs preact-master
  • todo: unsure 🔍 -1% - +4% (-0.01ms - +0.04ms)
    preact-local vs preact-master

Results

02_replace1k

duration

VersionAvg timevs preact-mastervs preact-local
preact-master154.81ms - 160.37ms-unsure 🔍
-3% - +2%
-5.25ms - +2.71ms
preact-local156.02ms - 161.70msunsure 🔍
-2% - +3%
-2.71ms - +5.25ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master3.75ms - 3.76ms-unsure 🔍
-0% - +0%
-0.01ms - +0.00ms
preact-local3.76ms - 3.77msunsure 🔍
-0% - +0%
-0.00ms - +0.01ms
-

run-warmup-0

VersionAvg timevs preact-mastervs preact-local
preact-master72.39ms - 75.82ms-unsure 🔍
-3% - +3%
-2.31ms - +2.48ms
preact-local72.35ms - 75.69msunsure 🔍
-3% - +3%
-2.48ms - +2.31ms
-

run-warmup-1

VersionAvg timevs preact-mastervs preact-local
preact-master97.98ms - 104.38ms-unsure 🔍
-5% - +4%
-5.52ms - +3.78ms
preact-local98.68ms - 105.43msunsure 🔍
-4% - +5%
-3.78ms - +5.52ms
-

run-warmup-2

VersionAvg timevs preact-mastervs preact-local
preact-master83.58ms - 87.25ms-unsure 🔍
-3% - +3%
-2.32ms - +2.58ms
preact-local83.65ms - 86.91msunsure 🔍
-3% - +3%
-2.58ms - +2.32ms
-

run-warmup-3

VersionAvg timevs preact-mastervs preact-local
preact-master67.76ms - 72.03ms-unsure 🔍
-5% - +4%
-3.83ms - +2.53ms
preact-local68.19ms - 72.91msunsure 🔍
-4% - +5%
-2.53ms - +3.83ms
-

run-warmup-4

VersionAvg timevs preact-mastervs preact-local
preact-master84.14ms - 91.45ms-unsure 🔍
-7% - +4%
-5.90ms - +3.56ms
preact-local85.96ms - 91.97msunsure 🔍
-4% - +7%
-3.56ms - +5.90ms
-

run-final

VersionAvg timevs preact-mastervs preact-local
preact-master154.84ms - 160.40ms-unsure 🔍
-3% - +2%
-5.25ms - +2.70ms
preact-local156.05ms - 161.74msunsure 🔍
-2% - +3%
-2.70ms - +5.25ms
-
03_update10th1k_x16

duration

VersionAvg timevs preact-mastervs preact-local
preact-master87.92ms - 90.24ms-unsure 🔍
-3% - +1%
-2.61ms - +0.77ms
preact-local88.77ms - 91.23msunsure 🔍
-1% - +3%
-0.77ms - +2.61ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master3.74ms - 3.74ms-unsure 🔍
-0% - +0%
-0.00ms - +0.01ms
preact-local3.73ms - 3.74msunsure 🔍
-0% - +0%
-0.01ms - +0.00ms
-
07_create10k

duration

VersionAvg timevs preact-mastervs preact-local
preact-master1606.24ms - 1639.36ms-unsure 🔍
-1% - +3%
-8.81ms - +41.10ms
preact-local1588.00ms - 1625.32msunsure 🔍
-3% - +1%
-41.10ms - +8.81ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master27.30ms - 27.30ms-unsure 🔍
-0% - -0%
-0.00ms - -0.00ms
preact-local27.30ms - 27.30msunsure 🔍
+0% - +0%
+0.00ms - +0.00ms
-
filter_list

duration

VersionAvg timevs preact-mastervs preact-local
preact-master221.32ms - 227.14ms-unsure 🔍
-3% - +1%
-5.89ms - +2.12ms
preact-local223.37ms - 228.87msunsure 🔍
-1% - +3%
-2.12ms - +5.89ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master1.77ms - 1.80ms-unsure 🔍
-1% - +1%
-0.02ms - +0.02ms
preact-local1.77ms - 1.80msunsure 🔍
-1% - +1%
-0.02ms - +0.02ms
-
hydrate1k

duration

VersionAvg timevs preact-mastervs preact-local
preact-master73.38ms - 76.08ms-unsure 🔍
-2% - +2%
-1.84ms - +1.84ms
preact-local73.48ms - 75.98msunsure 🔍
-2% - +2%
-1.84ms - +1.84ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master6.32ms - 6.33ms-unsure 🔍
-0% - +0%
-0.00ms - +0.01ms
preact-local6.32ms - 6.33msunsure 🔍
-0% - +0%
-0.01ms - +0.00ms
-
many_updates

duration

VersionAvg timevs preact-mastervs preact-local
preact-master127.87ms - 131.46ms-unsure 🔍
-2% - +2%
-2.41ms - +2.02ms
preact-local128.56ms - 131.15msunsure 🔍
-2% - +2%
-2.02ms - +2.41ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master5.37ms - 5.37ms-unsure 🔍
-0% - +0%
-0.00ms - +0.01ms
preact-local5.36ms - 5.38msunsure 🔍
-0% - +0%
-0.01ms - +0.00ms
-
text_update

duration

VersionAvg timevs preact-mastervs preact-local
preact-master66.53ms - 70.57ms-unsure 🔍
-4% - +4%
-2.68ms - +2.54ms
preact-local66.98ms - 70.26msunsure 🔍
-4% - +4%
-2.54ms - +2.68ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master0.95ms - 0.98ms-unsure 🔍
-3% - +2%
-0.03ms - +0.02ms
preact-local0.95ms - 0.98msunsure 🔍
-2% - +3%
-0.02ms - +0.03ms
-
todo

duration

VersionAvg timevs preact-mastervs preact-local
preact-master64.84ms - 66.55ms-unsure 🔍
-2% - +2%
-1.10ms - +1.39ms
preact-local64.65ms - 66.46msunsure 🔍
-2% - +2%
-1.39ms - +1.10ms
-

usedJSHeapSize

VersionAvg timevs preact-mastervs preact-local
preact-master1.02ms - 1.06ms-unsure 🔍
-4% - +1%
-0.04ms - +0.01ms
preact-local1.04ms - 1.08msunsure 🔍
-1% - +4%
-0.01ms - +0.04ms
-

tachometer-reporter-action v2 for Benchmarks

@coveralls
Copy link

coveralls commented Aug 23, 2021

Coverage Status

Coverage remained the same at 95.956% when pulling 4720d97 on restructure-controlled-components-2 into 5e8a3f9 on restructure.

@github-actions
Copy link

github-actions bot commented Aug 23, 2021

Size Change: +398 B (1%)

Total Size: 32.1 kB

Filename Size Change
dist/preact.js 4.59 kB +134 B (2%)
dist/preact.min.js 4.63 kB +134 B (2%)
dist/preact.umd.js 4.68 kB +130 B (2%)
ℹ️ View Unchanged
Filename Size Change
compat/dist/compat.js 3.52 kB 0 B
compat/dist/compat.umd.js 3.59 kB 0 B
debug/dist/debug.js 3.2 kB 0 B
debug/dist/debug.umd.js 3.3 kB 0 B
devtools/dist/devtools.js 232 B 0 B
devtools/dist/devtools.umd.js 316 B 0 B
hooks/dist/hooks.js 1.15 kB 0 B
hooks/dist/hooks.umd.js 1.23 kB 0 B
jsx-runtime/dist/jsxRuntime.js 342 B 0 B
jsx-runtime/dist/jsxRuntime.umd.js 425 B 0 B
test-utils/dist/testUtils.js 431 B 0 B
test-utils/dist/testUtils.umd.js 516 B 0 B

compressed-size-action

@developit
Copy link
Member

Question as I peek through here: does this require that a controlled input have an onInput handler in order to run patch() on every keystroke/change? Wondering if that gets blocked by shouldComponentUpdate and reverts back to uncontrolled.

@JoviDeCroock
Copy link
Member Author

JoviDeCroock commented Aug 23, 2021

@developit I'm not entirely sure I understand the question, controlled components as it stands require both a value and a notion of a changeHandler here being onInput if it bails out of an update due to return; it restores the previous value as that means a bailout. This never enters the diff so it's restored to the current stateful value.

This in no way meddles with our current uncontrolled components it's only a fix for our bug in controlled components when we bail out of updates due to the above example

@developit
Copy link
Member

Heh - sorry, I typed that out and didn't realize how vague it ended up being 😅

I was under the impression the following would be considered "controlled", and would not permit any user modification of the input:

function X() {
  return <input value="foo" />
}

You're saying the change handler is actually required in order to flip the input into controlled mode?

src/diff/mount.js Outdated Show resolved Hide resolved
src/diff/patch.js Outdated Show resolved Hide resolved
src/diff/props.js Outdated Show resolved Hide resolved
@marvinhagemeister
Copy link
Member

@JoviDeCroock This looks great! 🙌

I was under the impression the following would be considered "controlled", and would not permit any user modification of the input:

function X() {
  return <input value="foo" />
}

That's a good case we should cover in our tests 👍

@JoviDeCroock
Copy link
Member Author

@marvinhagemeister Yeah the test covers that case (in how far we can do that in JSDom) 😅

Copy link
Member

@marvinhagemeister marvinhagemeister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGMT 👍

@JoviDeCroock JoviDeCroock merged commit da2e759 into restructure Aug 30, 2021
@JoviDeCroock JoviDeCroock deleted the restructure-controlled-components-2 branch August 30, 2021 15:33
@EmmanuelOga
Copy link

Note: Reverted on #4008

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants