Hyperapp: Defining lifecycle methods when defining a component

Created on 7 Apr 2018  ·  7Comments  ·  Source: jorgebucaran/hyperapp

This issues follows on from some discussion in #general about how lifecycle methods work and @jorgebucaran suggest we bring it up here for discussion.

As a (very) new hyperapp user I’ve found it a little confusing that lifecycle methods can only be passed to a component at call time rather than when the component function itself is defined.

So something like this works:

const MyComponent = props => (
  <div>
    {props.name}
  </div>
);

<MyComponent
  name={"Sarah"}
  onupdate={(element, oldAttributes) => {
    console.log(oldAttributes.name) // "Max"
  }}
/>

While this does not:

const MyComponent = props => (
  <div onupdate={(element, oldAttributes) => {
    console.log(oldAttributes.name) // undefined
  }}>
    {props.name}
  </div>
);

<MyComponent name={"Sarah} />

Which is obviously because div is a different component to MyComponent. It is possible to work around this by passing the props you care about in onupdate to the div:

const MyComponent = props => (
  <div
    name={props.name}
    onupdate={(element, oldAttributes) => {
    console.log(oldAttributes.name) // undefined
  }}>
    {props.name}
  </div>
);

<MyComponent name={"Sarah} />

Or by wrapping MyComponent in a container that does essentially the same trick, but both these _feel_ inelegant and not all that obvious to me.

I’m wondering if there’s a way to make it possible to receive and act upon the oldAttributes for a component in a way that is _internal_ to the component itself, or whether HA’s functional paradigm precludes that possibilty (with purity as a payoff instead).

Discussion Feature Wontfix

Most helpful comment

Does this problem disappear when calling component functions directly (Component(props, children)), instead of using JSX (h(Component, props, children))?

@frenzzy I would move lifecycle events to component level and use VNodes only as a DOM node representation.

Interesting idea, but I think it would be slightly annoying to require a component anytime I want to use an oncreate handler. My own use of lifecycle events would have me vote for the opposite stance: components don't need lifecycle hooks. 🤷‍♂️

Maybe we should survey what people are using the lifecycle events for?

I'll start: I just searched my main project's codebase, and none of my lifecycle event handlers are useful at a component-level.

All of the oncreate handlers are attached directly to "normal" html elements. They do things like grab an element reference for use with vanilla JS stuff, or mount a 3rd party library (like the Google Maps Autocomplete input). In demos, I've also used them to trigger animations, which I also don't think is useful at the component-level, since you need the element reference.

I also have an onupdate handler which doesn't care about the props, and is just used to scroll a ul to the bottom when new list items are added.

All 7 comments

Components in Hyperapp are just plain functions which is used to be able to reuse multiple VNodes, nothing more. At the same time VNodes in hyperapp are too smart, they are represent real DOM nodes and also have lifecycle events aka components.

I would move lifecycle events to component level and use VNodes only as a DOM node representation. I believe this can make VNode easier to understand. No more custom oncreate and ondestroy events attached to real DOM nodes. Also components with lifecycle methods and which are not required to return VNodes are open a lot more opportunities from developer point of view.

I think if all components become lazy by default in HA 2.0, then we easily can add lifecycle events support for functional components.

Does this problem disappear when calling component functions directly (Component(props, children)), instead of using JSX (h(Component, props, children))?

@frenzzy I would move lifecycle events to component level and use VNodes only as a DOM node representation.

Interesting idea, but I think it would be slightly annoying to require a component anytime I want to use an oncreate handler. My own use of lifecycle events would have me vote for the opposite stance: components don't need lifecycle hooks. 🤷‍♂️

Maybe we should survey what people are using the lifecycle events for?

I'll start: I just searched my main project's codebase, and none of my lifecycle event handlers are useful at a component-level.

All of the oncreate handlers are attached directly to "normal" html elements. They do things like grab an element reference for use with vanilla JS stuff, or mount a 3rd party library (like the Google Maps Autocomplete input). In demos, I've also used them to trigger animations, which I also don't think is useful at the component-level, since you need the element reference.

I also have an onupdate handler which doesn't care about the props, and is just used to scroll a ul to the bottom when new list items are added.

Anyone else wants to add their thoughts/feedback? /cc @zaceno

The way I see it, our lifecycle events are about Element lifecycle - not component lifecycle. Hence it makes sense to me to set them on the vnodes only - NOT components.

I am with @zaceno
You can easily pass down lifecycle events to the root element of a Component.
Maybe the only thing Hyperapp can do by its own is to pass down these lifecycle events.

But IIRMC it is more an h thing.

@lili21 Yes.

Closing as I have no plans to add component-level lifecycle events in the foreseeable future.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamen picture jamen  ·  4Comments

icylace picture icylace  ·  3Comments

VictorWinberg picture VictorWinberg  ·  3Comments

SkaterDad picture SkaterDad  ·  3Comments

dmitrykurmanov picture dmitrykurmanov  ·  4Comments