This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-25
Channels
- # beginners (152)
- # boot (4)
- # bristol-clojurians (1)
- # cider (1)
- # cljs-dev (176)
- # clojure (104)
- # clojure-china (2)
- # clojure-uk (6)
- # clojurescript (6)
- # core-async (23)
- # cursive (4)
- # datomic (3)
- # devops (1)
- # duct (32)
- # events (1)
- # fulcro (9)
- # hoplon (2)
- # jobs-discuss (9)
- # lein-figwheel (2)
- # leiningen (3)
- # off-topic (19)
- # pedestal (2)
- # portkey (14)
- # re-frame (20)
- # reagent (41)
- # rum (4)
- # shadow-cljs (26)
- # tools-deps (1)
- # unrepl (5)
Can I have component that produces a heading tag, where the level of the heading is derived dynamically? So, for example, I’m passing an arg to the component that contains the heading keyword.
Any1 has some general tips/examples for how to implement the flip-animation in Reagent (https://medium.com/developers-writing/animating-the-unanimatable-1346a5aab3cd)? I've been bumping my head against the wall for a while now and I can't wrap my head around this
@smogg why not just use the JS implementation? You can import it and use it just fine.
@lee.justin.m react-flip-move
is great, but I needed a more custom behaviour. Plus I'm interested in how that translates into Reagent world. I failed with lifecycle methods tho.
@smogg it would be a very interesting project particularly if you open sourced it. what specifically were you having trouble with?
(the project I’d like to see translated is react-virtualized but that’s so freaking complicated)
The main problem was recreating the behaviour of looping over children while in in :component-did-update
. I tried using r/children
here and doing some magic but ended up with a lot of mess. An easier thing was to use :ref
on inner component and save the boundingClientRect()
there to some external state (typing example here so may be wrong, but the concept stays the same):
(def state (r/atom {}))
(for [{:keys [id name]} items]
[:div {:style (get-in @state [:items-tyles id])
:ref (fn [node]
(let [new-bounding-box (.getBoundingClientRect node)
old-bounding-box (get-in @state [:bounding-boxes id])
delta ....]
;; At this point I have everything I need to calculate the delta
;; so I'd do it, create styles, save the styles in the atom, use the generate styles above
(when-not (zero? delta)
(swap! state assoc-in [:item-styles id] {:transform (str "translateY(" delta "px)")}))
(swap! state assoc-in [:bounding-boxes id] new-bounding-box)
So basically I tried to move the logic to the :ref
part, which is probably wrong (and ended in an endless loop)
if I wanted to actually use :component-will-receive-props
and :component-did-update
then I don't even know how to get the children like in the React.js example in the article. Maybe I should r/reactify-component
at some point to make the r/children
fn actually return what I want
hm so there’s reagent.core/current-component
and reagent.core/children
, which I think return actual react children. I also think in form-3 components, the lifecycle methods get passed a “this” argument as the first argument and that, I think, is the same thing that reagent.core/current-component
returns, but I’m not sure and don’t have the ability to confirm right now
putting the logic in the :ref
seems like a really bad idea 🙂 I would be inclined to assoc
the children to a shared atom
if you were going to do it that way
So I think all r/children
does is it returns the arguments that you passed to the component.
If I had a component:
(defn comp [args & children] ...)
and I passed a vector to it: [:a :b :c]
then I'd just get that vector back, not actuall dom nodes with .getBoundingClientRect
methodBut the difference is that Reagent
component doesn't necessairly follow the [_ args & children]
pattern, unlike a React one
If you look at https://reagent-project.github.io/news/any-arguments.html it says Note: r/props and r/children correspond to React's this.props and this.props.children, respectively. They may be convenient to use when wrapping native React components, since they follow the same conventions when interpreting the arguments given.
which suggested to me that you’d get the actual mounted react components, not just hiccup. that’s why i included that section in the react interop document
if that doesn’t work, I think it should be able to just use javascript interop here: just grab the react component and access (.-children (.-props comp))
Well, yes - those methods would work with native react.js components. But to me it also means they might behave differently for Reagent component for differences I just mentioned
so:
(defn list-of-things*
[things]
[:div
(for [thing things]
[:div {:key thing} thing])])
(def list-of-things
(with-meta list-of-things*
{:component-did-mount
(fn [this]
(println "Children::" (r/children this)))}))
Yeah, I understood the docs as "this is a method for native react.js components" and looking a the source, this is what's happening: https://github.com/reagent-project/reagent/blob/master/src/reagent/impl/component.cljs#L49
So I thought I Could reactify component so that when I actually use r/children
it returns DOM thingies
probably less disruptive to just get the react component and then access its children
Maybe. But even if I do get the children, then how do I do the rest:
componentDidUpdate(previousProps) {
previousProps.children.forEach( child => {
let domNode = ReactDOM.findDOMNode( this.refs[child.key] );
const newBox = domNode.getBoundingClientRect();
const oldBox = this.state[key];
const deltaX = oldBox.left - newBox.left;
const deltaY = - ;
requestAnimationFrame( () => {
// Before the DOM paints, Invert it to its old position
domNode.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
// Ensure it inverts it immediately
domNode.style.transition = 'transform 0s';
});
});
}
i don’t quite udnerstand that implementation. is it taking one branch for reagent components and another for react
the domNode.style.transform
would indicate using set!
in cljs which seems totally wrong
so another way would be to update some external state that holds styles and use those in the render method
I find that when I’m writing cljs that is very close to something that is has inherently time-based mutations, you just need to write imperative code. otherwise you tie yourself in knots and end up with something that reads very unintuitively. i’m doing this kind of thing right now with a library that draws to a canvas element. there’s no obvious way to write elegant functional code