rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Deprecate the (action) template helper and modifier

Open NullVoxPopuli opened this issue 1 year ago • 1 comments

Propose deprecating the (action) template helper and modifier

Rendered

Summary

This pull request is proposing a new RFC.

To succeed, it will need to pass into the Exploring Stage), followed by the Accepted Stage.

A Proposed or Exploring RFC may also move to the Closed Stage if it is withdrawn by the author or if it is rejected by the Ember team. This requires an "FCP to Close" period.

An FCP is required before merging this PR to advance to Accepted.

Upon merging this PR, automation will open a draft PR for this RFC to move to the Ready for Released Stage.

Exploring Stage Description

This stage is entered when the Ember team believes the concept described in the RFC should be pursued, but the RFC may still need some more work, discussion, answers to open questions, and/or a champion before it can move to the next stage.

An RFC is moved into Exploring with consensus of the relevant teams. The relevant team expects to spend time helping to refine the proposal. The RFC remains a PR and will have an Exploring label applied.

An Exploring RFC that is successfully completed can move to Accepted with an FCP is required as in the existing process. It may also be moved to Closed with an FCP.

Accepted Stage Description

To move into the "accepted stage" the RFC must have complete prose and have successfully passed through an "FCP to Accept" period in which the community has weighed in and consensus has been achieved on the direction. The relevant teams believe that the proposal is well-specified and ready for implementation. The RFC has a champion within one of the relevant teams.

If there are unanswered questions, we have outlined them and expect that they will be answered before Ready for Release.

When the RFC is accepted, the PR will be merged, and automation will open a new PR to move the RFC to the Ready for Release stage. That PR should be used to track implementation progress and gain consensus to move to the next stage.

Checklist to move to Exploring

  • [ ] The team believes the concepts described in the RFC should be pursued.
  • [ ] The label S-Proposed is removed from the PR and the label S-Exploring is added.
  • [ ] The Ember team is willing to work on the proposal to get it to Accepted

Checklist to move to Accepted

  • [ ] This PR has had the Final Comment Period label has been added to start the FCP
  • [ ] The RFC is announced in #news-and-announcements in the Ember Discord.
  • [ ] The RFC has complete prose, is well-specified and ready for implementation.
    • [ ] All sections of the RFC are filled out.
    • [ ] Any unanswered questions are outlined and expected to be answered before Ready for Release.
    • [ ] "How we teach this?" is sufficiently filled out.
  • [ ] The RFC has a champion within one of the relevant teams.
  • [ ] The RFC has consensus after the FCP period.

NullVoxPopuli avatar Feb 13 '24 20:02 NullVoxPopuli

RFC Review (1) are happy for this to go to exploring. Over to RFC Review (2).

/cc @kategengler (just to bubble this up)

achambers avatar Feb 14 '24 16:02 achambers

Does this end up implicitly deprecating the classic class syntax? Is there a migration path for this kind of component which doesn't involve porting to ES6 class syntax first?

import Component from '@ember/component';
export default Component.extend({
  actions: {
    doThing() {
      this.thing;
    }
  }
});
<button {{action "doThing"}}>do</button>

Actually, is there even a way to write EmberComponents with ES6 class syntax? Does this proposal end up deprecating EmberComponents?

a13o avatar Feb 24 '24 22:02 a13o

Is there a migration path for this kind of component which doesn't involve porting to ES6 class syntax first?

yes! (see below)

Does this proposal end up deprecating EmberComponents?

It does not -- you can remain in the classic world by migrating to this.

import Component from '@ember/component';
import { action, set } from '@ember/object';

Component.extend({
  count: 0,
  increment: action(function () {
    set(this, 'count', this.count + 1);
  }),
});

Interactive demo here

is there even a way to write EmberComponents with ES6 class syntax?

There is! (and this is preferred!, and what was recommended during the era leading up to Octane, iirc)

looks like this:

import Component from '@ember/component';
import { tracked } from '@glimmer/tracking';

export default class Demo extends Component {
  @tracked count = 0;
  increment = () => this.count++;
}

Interactive demo here

And even with ember components, you can use the latest format, GJS, which looks like this:

import Component from '@ember/component';
import { tracked } from '@glimmer/tracking';
import { on } from '@ember/modifier';

export default class Demo extends Component {
  @tracked count = 0;
  increment = () => this.count++;

  <template>
    <p>Clicked: {{this.count}}</p>
  
    <button {{on 'click' this.increment}}>click</button>
  </template>
}

Personally, I'd opt to go straight to gjs (and glimmer) at that point (IFF there are sufficient tests for the component that is -- I like safe migrations 😅 )

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { on } from '@ember/modifier';

export default class HelloWorld extends Component {
  @tracked count = 0;

  increment = () => this.count += 1;

  <template>
    <p>Count: {{this.count}}</p>

    <button {{on "click" this.increment}}>Click</button>
  </template>
}

(note that this is nearly identical (DX-wise) to the ember component version, except you'll inherently get a slight perf boost, due to glimmer components just being less complex)

NullVoxPopuli avatar Feb 24 '24 23:02 NullVoxPopuli

Phew! Porting all those classic components to the prop: action() syntax isn't so bad.

For porting them to ES6, the next smallest hop would probably be something like this

a13o avatar Feb 24 '24 23:02 a13o

ember-native-class-codemod will get your ember components to es6 syntax, for the most part.

kategengler avatar Feb 25 '24 02:02 kategengler