mirror of https://github.com/status-im/reagent.git
Add doc about controlled inputs & workarounds
This commit is contained in:
parent
d809a5a202
commit
2d0ec89ad7
|
@ -0,0 +1,30 @@
|
||||||
|
# Controlled inputs
|
||||||
|
|
||||||
|
Reagent uses async rendering which cause problems with controlled inputs. If
|
||||||
|
the input element is created directly by Reagent (i.e. `[:input ...]` in hiccup), [a
|
||||||
|
workaround](https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/template.cljs#L132-L238)
|
||||||
|
can be applied, but if the input is created by JS library (i.e. JSX `<input>`
|
||||||
|
or React `create-element`), Reagent doesn't see
|
||||||
|
the element so the workaround can't be applied.
|
||||||
|
|
||||||
|
Due to async rendering, the DOM update doesn't occur during the event handler,
|
||||||
|
but some time later. In certain cases, like when the cursor is not at the end
|
||||||
|
of the input, updating the DOM input value causes the cursor to move to the
|
||||||
|
end of the input. Without async rendering, browsers probably implement logic
|
||||||
|
to keep the cursor position if the value is updated during event handler.
|
||||||
|
|
||||||
|
Reagent workaround works by changing the React input element into
|
||||||
|
uncontrolled input (i.e. the DOM value is not updated by React). Instead
|
||||||
|
Reagent will update DOM itself if the Reagent input value property changes.
|
||||||
|
This enables Reagent to check the cursor position before updating the
|
||||||
|
value, and if needed, save and restore the cursor position
|
||||||
|
after updating the value.
|
||||||
|
|
||||||
|
For JS libraries, usually the best solution is if the library provides an option to
|
||||||
|
use custom component to create the input element, which enables
|
||||||
|
Reagent to create the input element:
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
- [Material UI](./examples/material-ui.md)
|
||||||
|
- [Smooth UI](./examples/smooth-ui.md)
|
|
@ -8,7 +8,8 @@
|
||||||
["[WIP] Managing State: atoms, cursors, Reactions, and tracking" {:file "doc/ManagingState.md"}]
|
["[WIP] Managing State: atoms, cursors, Reactions, and tracking" {:file "doc/ManagingState.md"}]
|
||||||
["Batching and Timing: How Reagent Renders Changes to Application State" {:file "doc/BatchingAndTiming.md"}]
|
["Batching and Timing: How Reagent Renders Changes to Application State" {:file "doc/BatchingAndTiming.md"}]
|
||||||
["Interop with React" {:file "doc/InteropWithReact.md"}]
|
["Interop with React" {:file "doc/InteropWithReact.md"}]
|
||||||
["React Features" {:file "doc/ReactFeatures.md"}]]
|
["React Features" {:file "doc/ReactFeatures.md"}]
|
||||||
|
["Controlled Inputs" {:file "doc/ControlledInputs.md"}]]
|
||||||
["Frequently Asked Questions" {}
|
["Frequently Asked Questions" {}
|
||||||
["Why isn't my Component re-rendering?" {:file "doc/FAQ/ComponentNotRerendering.md"}]
|
["Why isn't my Component re-rendering?" {:file "doc/FAQ/ComponentNotRerendering.md"}]
|
||||||
["How do I use React's \"refs\"" {:file "doc/FAQ/UsingRefs.md"}]
|
["How do I use React's \"refs\"" {:file "doc/FAQ/UsingRefs.md"}]
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Smooth UI
|
||||||
|
|
||||||
|
Smooth UI has the same problem with [controlled inputs](../CotrolledInputs.md)
|
||||||
|
as [Material UI](./material-ui.md).
|
||||||
|
The problem can be solved by providing custom component to Smooth UI inputs
|
||||||
|
which will create the Input element using Reagent, enabling Reagent to use
|
||||||
|
it's workaround logic to control input value and cursor position:
|
||||||
|
|
||||||
|
```cljs
|
||||||
|
(def r-input (r/reactify-component
|
||||||
|
(fn [props]
|
||||||
|
;; Omit:
|
||||||
|
; https://github.com/smooth-code/smooth-ui/blob/c5f3c75a438a04e766dbedeafc2be54252a5338e/packages/shared/core/createComponent.js#L31
|
||||||
|
; https://github.com/smooth-code/ smooth-ui/blob/c5f3c75a438a04e766dbedeafc2be54252a5338e/packages/shared/core/Input.js#L84
|
||||||
|
;; Maybe also:
|
||||||
|
; (.. system -meta -props)
|
||||||
|
[:input (dissoc props :__scTheme :theme :control :size :valid)])))
|
||||||
|
|
||||||
|
(r/render [:> Input {:as r-input ...}] container)
|
||||||
|
```
|
Loading…
Reference in New Issue