【问题标题】:Why should we avoid side-effects in components constructors?为什么我们应该避免组件构造函数中的副作用?
【发布时间】:2020-04-03 21:12:22
【问题描述】:

我想知道是否有充分的理由不在组件的构造函数中而不是在其componentDidMount 钩子中发送请求?我已经看到一些interesting (but a bit incomplete) answers 用于:在构造函数中获取数据是个好主意吗?答案引用了文档中的一个有趣的部分:

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

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

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

在构造函数中发送请求

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

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

或发送至componentDidMount

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

或者按照链接问题中的建议,绝对不好的一个:在构造函数中获取

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

    async componentDidMount() {
        this.setState({'data': this.data});
    }
}

【问题讨论】:

  • 这能回答你的问题吗? Fetching data in constructor
  • 不,它不完全(问题不同,因此我的答案不准确)。虽然我的问题很清楚:我自己链接了这个问题,并解释了为什么这两个问题与我的第一个代码示例不同。我将添加第三段代码再次强调这一点。
  • 我知道你链接了它,但是对我来说,这个问题与你链接的另一个问题并没有太大的不同,所以我投票决定将它作为那个问题的副本关闭(措辞是堆栈溢出的这样做会生成自动评论)。您可能希望编辑您的问题以突出它的不同之处,以及为什么其他问题的答案不足。
  • 对不起,我不明白你不明白的地方。
  • 从对该问题的回答中获得了 12 票赞成:“在安装组件之前调用了构造函数……如果您在构造函数中调用 setState,您的组件有时不会重新渲染。”您对此有哪些具体问题没有涵盖?您似乎有这种将 React 组件同步映射到 DOM 的心理模型,但这不是 React 的工作方式:它将 DOM 访问批处理作为性能优化,并且它不允许您在未安装的组件上调用 setState 到其他事情有助于调试。所有这些都包含在文档中。

标签: reactjs react-native asynchronous fetch side-effects


【解决方案1】:

好的,有多种原因:

  1. 您的副作用在服务器端渲染中并不总是有意义甚至可运行,并且在 SSR 中 componentDidMount 钩子不会被调用,您的拆卸逻辑也不会运行
  2. 它可能会触发意外的setState,在this answer 中解决
  3. 在某些情况下组件会被构造,但不会被挂载或稍后会被挂载,在它们的构造函数中调用副作用是没有意义的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-15
    • 2021-11-16
    • 2020-03-24
    • 2013-01-14
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多