This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-05
Channels
- # announcements (1)
- # babashka (7)
- # beginners (60)
- # biff (7)
- # cider (2)
- # clj-kondo (1)
- # clojure (15)
- # clojure-france (1)
- # clojure-norway (1)
- # clojurescript (7)
- # datascript (7)
- # emacs (4)
- # etaoin (1)
- # honeysql (7)
- # interceptors (8)
- # introduce-yourself (3)
- # kaocha (1)
- # off-topic (16)
- # pathom (2)
- # reagent (15)
- # reitit (11)
- # releases (1)
- # slack-help (3)
- # vim (36)
hey all - how can I pass a property on to a component with a -
intact? I am passing :fonts-directory
and reagent seems to be passing it along as fontsdirectory
.
an underscore will survive, but not a dash
[:math-field {:ref js/console.log
:fonts-directory ""}
"face" " cake"]
wait - forgot we’re on the pro plan and searched. I’m set! (using a string works)
Question… when a component in react like textarea doesn’t re-render on a change to some property like defaultValue, how is it doing that? I am writing a component that is a light wrapper over a textarea-like thing and want to make sure that it behaves this way too. The underlying thing is a “math-field”, so I need to reimplement the value / defaultValue pair of keys and their behavior.
Currently using function components and hooks
a lot of it is specific to the way React interacts with the DOM. I'm not sure that how React implements textarea is actually relevant to what you're doing
Fair - maybe a better question is, what way would you recommend for making a component where some property does not trigger a re render even if changed
Hi Sam,
AFAIK defaultValue
is a regular HTML attribute (https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement),
If you modify it, the element does not visually change. I believe that react/reagent "re-render" still happens, the difference in the dom is detected, and the defaultValue is updated to the new value, but the new value has no effect. Sorry if that seems pedantic, but I think it's important to point out that the attribute is "non-reactive" by HTML behavior more than anything in react/reagent.
So to answer your question more directly, you could create a component that takes an initial input but will never change the dom on updated inputs by doing something like:
(defn widget [message]
(let [actual-message message]
(fn [message]
[:div actual-message])))
^^ This will use the input during construction, but then ignore the input on future renders. Re-renders will still occur but they will be effectively a no-op, as nothing changed. (You could do a similar thing in with-let or using the component form).
Hope that helps, sorry if I'm way off@U017QJZ9M7W I guess I'm also confused about "does not trigger a re render even if changed." I think that could be the wrong way to think about it.
Could you explain the behavior you want? e.g. "When I pass in the default-value
prop to the text input, it uses that as the value on first render, and then any changes to it do not change the value of the text input."
Also, what have you tried so far? Are you having some specific issues trying to implement the behavior you want? ATM the question is very general, and it sounds like there might be more details both to the behavior you want and the technical implementation - e.g. it sounds like you might be using either a third party library ("text area-like thing") or you're building a complex component yourself.
To try and answer your original question, though, you can avoid re-rendering a component by memoizing it. See the React docs on React.memo
and React.useMemo
. These can be used to control when certain computations happen, including the re-creation of elements that React uses to determine whether any changes to the page must happen.
I think what you might actually want though is a higher level pattern: to initialize some internal state in your component and then have the component be either "uncontrolled" (i.e. the component has internal state determining its display & behavior that doesn't react to outside changes) or "controlled" (i.e. the component's state is external to it, props passed to it determine its display & behavior). Memoization & avoiding renders might be the way to do this, but IME probably not; if you're avoiding re-renders, it's usually either for performance reasons OR you're doing some weird mutable DOM manipulation (likely wrong). So that's why it's useful to know exactly what you're trying to do, as implementing this pattern of toggling between either "controlled" or "uncontrolled" can be tricky in practice.
@U4YGF4NGM my question was vague; I am wrapping a math-field
web component from this library: https://cortexjs.io/mathlive/demo/, and just like a textarea it takes children.
what saved me here was that I realized that it treats its single string child like a defaultValue
, so I can
1. pass along (or default-value value "")
from my top-level component, and then
2. use a hook that triggers on changes to my value
property to call .setValue
on the MathfieldElement
reference.
@U4YGF4NGM here is what I have so far (don’t treat the code comments as final, this is all coming together now!) https://gist.github.com/sritchie/aabc0895ac6c831f379a0212265cc9d8