# Mostly clueless

but curious to find out
May 19, 2016

# Props, Children & Component Lifecycle in Reagent

Every now and then I come across the situation that I need to compare previous and next props passed to a Reagent component. Every time again I fail to find some docs and figure it out by trial and error.

## Props vs. Children

In React everything passed to a component is called `props`. Children passed to components are passed as `props.children`. In Reagent things are a bit different and Reagent’s hiccup syntax doesn’t explicitly separate the two:

    ;; configuration and one child
    [popup {:style :alert} [delete-confirmation]]
    ;; two children
    [popup [alert-icon] [delete-confirmation]]

    <Popup style="alert"><DeleteConfirmation></Popup>

In React it is well-defined where you can access the `style` parameter (`props.style`) and how you can access the passed children (`props.children`).

In Reagent things are a bit different: you have a function definition which takes a number of arguments which you can just refer to in the same way you can refer to any other function parameter. This makes thinking in functions a lot easier but also overshadows some of the underlying React behaviour.

In a lifecycle handler like `:component-did-update` accessing component arguments via the symbol they’ve been given in the functions argument vector doesn’t work:

The moment you define components that are not simple render functions (remember those Form-2 and Form-3 components?) all updates will pass their arguments to the components render function.

The moment you render a component that has been created via `reagent.core/create-class` all updates will pass their arguments to the `:reagent-render` function, potentially triggering a re-render. The function that returned the result of `create-class` is only ever called once at the time of mounting the component — your top-level `defn` returns a component instead of being a render function itself. This is also why you need to repeat the arguments in the `:reagent-render` arguments.

## Props in Lifecycle Handlers

Now how do we get access to these props in a lifecycle handler? The quick answer is, we use `reagent.core/props` — obvious, huh?

One peculiarity about the `props` function is that it expects the `props` data to be the first argument to your function. Also it has to be a map (if it’s not `props` returns `nil`).

If the first argument to your component is not a map all arguments are interpreted as children and can be retrieved via `reagent.core/children`.

So now we have the props for the current render, how do we access the previous ones? All previously passed arguments are passed to the lifecycle handler. Not as you might think though.

If you have a component that has a signature like this:

    (defn my-comp [my-props more] …)

You can access it’s previously passed arguments like this:

    :component-did-update (fn [comp [_ prev-props prev-more]] …))

`comp` is a reference to the current component. The second argument which is being destructured here contains what we’re looking for. As far as I understood the first item is the component's constructor. The rest are the previously rendered inputs (again in React they’re all `props`, in Reagent they’re `props` and `children`).

As you can see you can inspect all previous arguments to a component. The way you access them differs from the default React lifecycle method signatures so hopefully this post helps to clear up some confusion about this stuff. :)

Thanks to Jonas Enlund for reading a draft of this post and to Mike Thompson for his excellent Re-frame/Reagent docs.