33

This blog is talking about things we can do with lwc connectedCallback method. It seems to contradict itself with a certain point so I am trying to make sure.

They say that we can set property values in a connectedCallback. After that they say the following:

Do not use connectedCallback() to change the state of a component, such as loading values or setting properties. Use getters and setters instead.

This is confusing, is this some bad practice or something? I am using connectedCallback to query the server on initial load and I normally set the property in the method and it works. Just wondering if there is something I am missing here.

4
  • 12
    This line of text comes straight from the documentation, but there's apparently no reasoning why or an example of how to do it "properly". As far as I'm aware, practically everyone (including myself) has violated this rule at least once without consequence. I'm going to ask around about this, and see if we can't get some clarification.
    – sfdcfox
    Commented Feb 18, 2021 at 11:36
  • 3
    I think it is warning of implications that a component might do a rerender if the is changed, I feel we can break this rule for connectedCallback but we have to be very careful when doing it with renderedCallback. Commented Feb 18, 2021 at 12:12
  • 1
    The thing is it's very circular. They say do not change the state of the component and use getters and setters, but what do the getters/setters do other than change the state of the component? :) Commented Feb 18, 2021 at 13:39
  • I guess what they mean is - use default property initializers, getters/setters where possible and put into connectedCallback more complex logic such processing initial input from parents, doing some initial requests to server (where wire doesn't work) and etc.
    – ytiq
    Commented Feb 22, 2021 at 9:15

1 Answer 1

48

This is in fact a mistake in the LWC documentation. We are currently working on rewriting this section entirely.

The connectedCallback lifecycle hook is invoked when a component is connected to the document. This callback is invoked after all the public properties are set and can be used to set the state of the component.


As I see it, the original author was trying to warn about the fact that public properties can be updated after the connectedCallback is invoked. The connectedCallback is invoked only one time with the initial properties passed to the component. If a component derives its internal state from the properties, it's better to write this logic in a setter than in connectedCallback.

To illustrate this better, let's create a component that renders a random dog picture given its breed. We can first define a utility method to fetch the dog image.

function getPicture(breed) {
  return fetch(`https://dog.ceo/api/breed/${breed}/images/random`)
        .then(responce => responce.json())
        .then(res => res.message);
}

In the component below, the getPicture method is invoked in the connectedCallback. The imageUrl property is derived from the breed public property. Since the logic is in the connectedCallback, the imageUrl will always have the value of the initial breed value. This is not ideal for our component.

export default class DogImage extends LightningElement {
  @api breed;
  imageUrl;

  connectedCallback() {
    getPicture(this.breed).then(res => {
      this.imageUrl = res;
    });
  }
}

To solve this issue, expose breed using a getter/setter pair and move the logic there. Every time the breed public property is set, the setter is invoked and a new picture is fetched.

export default class DogImage extends LightningElement {
  imageUrl;
  _breed;

  @api
  set breed(value) {
    if (this._breed !== value) {
      this._breed = value;
      
      getPicture(value).then(res => {
        this.imageUrl = res;
      });
    }
  }
  get breed() {
    return this._breed;
  }
}

Live example: playground

1
  • Great answer, you just answered a day or two too late to grab the bounty. :( Commented Mar 5, 2021 at 15:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .