From 8e639a8ff995bf6b93d9104e1888c2ccd9fc54e4 Mon Sep 17 00:00:00 2001 From: Keith Cirkel Date: Fri, 19 Feb 2021 15:24:30 +0000 Subject: [PATCH] docs: add "things to remember" in lifecycle callbacks --- docs/_guide/lifecycle-hooks.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/_guide/lifecycle-hooks.md b/docs/_guide/lifecycle-hooks.md index 95f5d624..924880fc 100644 --- a/docs/_guide/lifecycle-hooks.md +++ b/docs/_guide/lifecycle-hooks.md @@ -11,6 +11,12 @@ The [`connectedCallback()` is part of Custom Elements][ce-callbacks], and gets f JavaScript traditionally uses the `constructor()` callback to listen for class creation. While this still works for Custom Elements, it is best avoided as the element won't be in the DOM when `constructor()` is fired, limiting its utility. +#### Things to remember + +The `connectedCallback` is called _as soon as_ the element is attached to a `document`. This _may_ occur _before_ an element has any children appended to it, so you should be careful not expect an element to have children during a `connectedCallback` call. This means avoiding checking any `target`s or using other methods like `querySelector`. Instead use this function to initialize itself and avoid doing initialization work which depend on children existing. + +If your element depends heavily on its children existing, consider adding a [`MutationObserver`](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) in the `connectedCallback` to track when your elements children change. + ### `attributeChangedCallback()` The [`attributeChangedCallback()` is part of Custom Elements][ce-callbacks], and gets fired when _observed attributes_ are added, changed, or removed from your element. It required you set a `static observedAttributes` array on your class, the values of which will be any attributes that will be observed for mutations. This is given a set of arguments, the signature of your function should be: @@ -19,6 +25,10 @@ The [`attributeChangedCallback()` is part of Custom Elements][ce-callbacks], and attributeChangedCallback(name: string, oldValue: string|null, newValue: string|null): void {} ``` +#### Things to remember + +The `attributeChangedCallback` will fire whenever `setAttribute` is called with an observed attribute, even if the _new_ value is the same as the _old_ value. In other words, it is possible for `attributeChangedCallback` to be called when `oldValue === newValue`. In most cases this really won't matter much, and in some cases this is very helpful; but sometimes this can bite, especially if you have [non-idempotent](https://en.wikipedia.org/wiki/Idempotence#Computer_science_examples) code inside your `attributeChangedCallback`. Try to make sure operations inside `attributeChangedCallback` are idempotent, or perhaps consider adding a check to ensure `oldValue !== newValue` before performing operations which may be sensitive to this. + ### `disconnectedCallback()` The [`disconnectedCallback()` is part of Custom Elements][ce-callbacks], and gets fired as soon as your element is _removed_ from the DOM. Event listeners will automatically be cleaned up, and memory will be freed automatically from JavaScript, so you're unlikely to need this callback for much.