Closed ItsJonQ closed 3 years ago
This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.
🔍 Inspect: https://vercel.com/itsjonq/g2/8m40t6zyb
✅ Preview: https://g2-git-try-refactor-text-input-prop-state-handling.itsjonq.vercel.app
Good work sorting out a generic solution for this.
This update improves how state (
value
from props) is handled, transformed, and derived for controlled components, such asTextInput
,UnitInput
,Select
,Slider
, andSearchInput
.This was originally brought to light by @jorgefilipecosta in https://github.com/ItsJonQ/g2/issues/203. After ideas were shared within the Gutenberg integration PR, @saramarcondes and I took a closer look.
We started refactoring out
zustand
, which revealed some sync. issues with props/state. We were successful in some refactors (such asSelectDropdown
), but unsuccessful in others (such asColorPicker
).The culmination of this journey (from
zustand
sync to recent refactors) has highlighted a good path forward for how we can reliably handle controlled components in a simple and stable fashion.useControlledValue()
We needed an elegant and seamless way to handle value/state sync and defaultValue fallbacks for our controlled components. The solution I came up was this:
It's the successor to
useControlledState
. It's pretty simple! Ifvalue
is defined, use that. Otherwise, fallback tostate
. (Same foronChange
).usePropRef()
Another improvement is the addition of
usePropRef
. This simulates the "selector" benefits that zustand provided for callback functions. By creating a ref for a collection of props, this collection can be passed intouseCallback
based functions without breaking dependency equality.For
TextInput
, this ensures thatincrement
anddecrement
doesn't change per render cycle. This is useful as actions (and others) are used throughout the component.From that, I refactored the previous
zustand
setup actions, selectors, etc... to callback functions and derived values (suggested by @jorgefilipecosta ).From my tests, it looks like it worked!
Demo
The easiest place to test would be here: https://g2-git-try-refactor-text-input-prop-state-handling.itsjonq.vercel.app/iframe.html?id=components-unitinput--default&viewMode=story
Examples
I've created a couple of CodeSandbox examples for the 2 new hooks
useControlledValue https://codesandbox.io/s/use-controlled-value-kdpcg?file=/src/App.js
usePropRef https://codesandbox.io/s/use-prop-ref-examples-4eowp
The big ones, that being
TextInput
andUnitInput
, look like they're working as expected.I suspect with these changes, we'll be able to complete the ColorPicker refactor. From my tests, I suspect the infinite looping issue is being caused by incompatible render cycles between controlled components.
🙏