为什么我们应该避免组件构造函数中的副作用?

cgl*_*cet 6 asynchronous side-effects fetch reactjs react-native

我想知道是否有充分的理由不在组件的构造函数中而不是在其componentDidMount钩子中发送请求?我看到了一些有趣的(但有点不完整)的答案在构造函数中获取数据是个好主意吗?答案引用了文档中有趣的一点:

避免在构造函数中引入任何副作用或订阅。对于这些用例,请改用 componentDidMount()。

我的问题是关于这一点,我很想知道副作用有什么问题,例如在这里在构造函数中发送请求。

也许一个简单的例子将有助于消除关于我的问题和链接问题之间差异的任何歧义:

在构造函数中发送请求

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

    async componentDidMount() {
        const data = await this.request;
        this.setState({'data': data});
    }
}
Run Code Online (Sandbox Code Playgroud)

或者寄过来 componentDidMount

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

或者如链接问题中所建议的那样,绝对不好:在构造函数中获取

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

    async componentDidMount() {
        this.setState({'data': this.data});
    }
}
Run Code Online (Sandbox Code Playgroud)

Aus*_*ras 2

好吧,原因有很多:

  1. 你的副作用并不总是有意义的,甚至不会在服务器端渲染中运行,并且在 SSRcomponentDidMount钩子中不会被调用,你的拆卸逻辑也不会运行
  2. 它可能会触发本答案setState中解决的意外情况
  3. 在某些情况下,组件将被构造,但不会被安装或稍后被安装,并且在其构造函数中调用副作用是没有意义的