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"}]
|
||||
["Batching and Timing: How Reagent Renders Changes to Application State" {:file "doc/BatchingAndTiming.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" {}
|
||||
["Why isn't my Component re-rendering?" {:file "doc/FAQ/ComponentNotRerendering.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