Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should we avoid side-effects in components constructors?

I wonder if there is a good reason not to send requests in the constructor of a component instead of in its componentDidMount hook? I've seen some interesting (but a bit incomplete) answers for: is it a good idea to fetch data within the constructor? the answer quotes an interesting bit from the documentation:

Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, use componentDidMount() instead.

My question is about this point, I'm curious to understand what's the problem with side-effects like for example here sending a request in the constructor.

Maybe a quick example will help removing any ambiguity about the difference between my question and the linked one:

Sending request within the constructor

class SomeComponent extends React.Component {
    constructor(props) {
        this.request = fetch(props.someURL);
    }

    async componentDidMount() {
        const data = await this.request;
        this.setState({'data': data});
    }
}

Or sending it in componentDidMount

class SomeComponent extends React.Component {
    async componentDidMount() {
        const data = await fetch(props.someURL);;
        this.setState({'data': data});
    }
}

Or as suggested in the linked question, the definitely bad one: fetching in the constructor

class SomeComponent extends React.Component {
    constructor(props) {
        this.data = await fetch(props.someURL);
    }

    async componentDidMount() {
        this.setState({'data': this.data});
    }
}
like image 893
cglacet Avatar asked Apr 03 '20 21:04

cglacet


1 Answers

Ok, there're multiple reasons:

  1. Your side effect won't always be meaningful or even runnable in server-side render, and in SSR componentDidMount hook won't be called, your teardown logic won't be run either
  2. It may trigger unintended setState which is addressed in this answer
  3. In some circumstance component will be constructed, but won't be mounted or will be mounted later, and call side effect in their constructor is meaningless
like image 109
Austaras Avatar answered Nov 12 '22 21:11

Austaras