Vs.

Component Lifecycle

Initialization

Because Ember uses classes, we need to use the constructor() method to run some code on initialization. With React, anything written in the body of the function will run every time the component re-renders, similar to didRecieveAttrs. To run code once per component initialization, the useEffect hook is needed.

Ember

import Component from '@glimmer/component';

export default class MyComponent extends Component {
  constructor() {
    super(...arguments);
    console.log("Component initialized");
  }
}

React

import { useEffect } from 'react';

export default function MyComponent() {
	useEffect(() => {
		console.log("Component initialized");
	}, []) // Empty array as the second parameter means run this effect once. 
}

Deconstructor

Ember Octane (Glimmer components) can run code when destroying the component using the willDestroy method. React can run code when destroying (unmounting) a component, this is done using the same useEffect hook. The hook’s return value can be a function, this function is called once the component unmounts and the effect is destroyed.

Ember

import Component from '@glimmer/component';

export default class MyComponent extends Component {
	willDestroy() {
		console.log("Cleanup code..");
	}
}

React

import { useEffect } from 'react';

export default function MyComponent({ firstName, lastName }) {
	useEffect(() => {
		// Avoid having multiple useEffect hooks, the setup code should 
		// be run in the same block as the cleanup code.
		return () => {
			console.log("Cleanup code..")
		}
	}, []);
}

Modifiers vs Hooks

Ember modifiers allow us to attach functions to different portions of the ember rendering cycle, this is similar to the various react hooks we get access to.

did-insert

Ember

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

export default class MyComponent extends Component {
  @action modifyElement(element) {
    // You have the element.
  }
}
<canvas {{did-insert this.modifyElement}}></canvas>

React

import { useEffect } from 'react';

export default function MyComponent() {
	const element = <canvas></canvas>
	useEffect(() => {
		// Have access to the element here.
	}, []);
	return element;
}

did-update

Ember

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

export default class extends Component {
  @action
  resizeArea(element) {
    element.style.height = `${element.scrollHeight}px`;
  }
}
<textarea {{did-update this.resizeArea @text}}>
  {{@text}}
</textarea>

React

import { useEffect } from 'react';

export default function MyComponent({ text }) {
	const element = (<textarea></textarea>)
	useEffect(() => {
		element.style.height = `${element.scrollHeight}px`;
	}, [text]);
	return element;
}
Previous
Component Properties