为啥react的组件要super

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥react的组件要super相关的知识,希望对你有一定的参考价值。

    原因

    调用super的原因:在ES6中,在子类的constructor中必须先调用super才能引用this。

    super(props)的目的:在constructor中可以使用this.props。

    最后,可以看下React文档,里面有一段:

    在es6中实现继承,直接调用super(name),就可以直接继承父类的属性和方法,所以super作用就相当于上述的实现继承的步骤,不过es6提供了super语法糖,简单化了继承的实现。

参考技术A 1. 父组件 -> 前几层子组件: props

2. 父组件 -> 非常深入的子组件(比如从最顶层到第5层以后): context
这种情况几乎很少见,除非写框架或者工具,最好是只用props,清晰明了

3. 子组件 -> 父组件:callback

4. 子组件时间: 严格意义上不存在这种情况,如果出现这样的需求,说明你的写法是错误的,
数据的流向始终都应该是从顶至下。例如root -> (A,B,C) 所以A组件改变,需要让B改变时,A调用root以props传来的callback从而导致root的state发生变化,这样B就能得到更新

5.

当APP复杂的可能特殊情况:在使用pureRenderMixin来提升渲染速度的时候,非常里层的子组件需要一些参数来计算显示的值,但是你又不需要
当这个值改变的时候重新渲染这个组件而且也不想用context的时候, 在Root中定义this.getAllState= () =>
this.state, 然后将这个getAllState作为props传递给子组件; 这种情况很少出现,慎用

6.使用某种Flux,让局部组件链接一个自己的store,同时接受来自父组件的各种callback props, 通过这些callback实现 小组件的store改变时,通知父组件

在一个实际的APP中的实际情况是如何设计store和props的呢?
其实重点,我认为是store和store之间是如何交流数据的。
这里我斗胆地拿我在家写的一个编辑器来做一些分析:编辑器端Flommox, 播放器向redux迁移中
整个编辑器网站分成了不同的页面,每个页面(例如/course:id, /editor/:id, /quizs)对应一个Action分组+一个Store, 有的复杂页面可能需要很多歌store整个编辑器网站分成了不同的页面,每个页面(例如/course:id, /editor/:id, /quizs)对应一个Action分组+一个Store, 有的复杂页面可能需要很多歌store


个编辑器使用了不止一个store,在初次渲染是先隐藏了『资源弹出框』『习题弹出框』他们分别有自己的store,但是他们是否显示是由父组件的
store控制的,具体的数据交流第6点已经简单的说明了。有些flux框架可以让一个函数作为Action,那么这个就可以作为callback进行数
据交流了。

更好的方式:直接在Action里传递Promise, 甚至Observable

更更好的方式:使用Redux 的middleware, 在一个Action发送途中去做异步请求其他store的数据,Redux的Action中也可以传递thunk, promise,Observable ,function等,尽量少用callback,让整个APP更加functional programming, 更好管理本回答被提问者采纳

理解为啥在 React 类组件中不推荐使用 super()

【中文标题】理解为啥在 React 类组件中不推荐使用 super()【英文标题】:Understanding why super() is deprecated in a React class component理解为什么在 React 类组件中不推荐使用 super() 【发布时间】:2020-12-30 13:28:34 【问题描述】:

我是 React 新手,我正在使用最新版本的 React 了解 React 组件生命周期。我对下面部分代码的“超级”调用带有已弃用的警告标记。我很难理解这一点,因为那里的许多文档仍然使用“超级”,而且我不确定继任者是什么,即使来自反馈中链接的完整文章也是如此。有任何想法吗?谢谢。

class App extends Component 
  constructor(props) 
    super(props);
  

这里是警告:

constructor React.Component<any, any, any>(props: any, context?: any): React:Component<any, any, any> (+1 overload)
@deprecated
@see - https://reactjs.org/docs/legacy-context.html
'(props: any, context?: any): Component<any, any, any>' is deprecated ts(6385)

【问题讨论】:

可能是 React native context and deprecated super usage 的副本?这里没有context,代码其实没问题,警告错了。 【参考方案1】:

只有在构造函数中使用this.props 时,才需要super(props);。否则你可以使用super(); 如果在构造函数中使用super();,那么在构造函数之外调用this.props 不是问题。 您可以在以下链接中了解它: https://overreacted.io/why-do-we-write-super-props/

class Button extends React.Component 
  constructor(props) 
    super(); //we forgot to pass props
    console.log(props); //
    console.log(this.props); //undefined
  
  // ...

如果这发生在从构造函数调用的某个方法中,则可能更具挑战性。这就是为什么我建议始终传递super(props),即使没有必要。

class Button extends React.Component 
  constructor(props) 
    super(props); //we passed props
    console.log(props); //
    console.log(this.props); //
  
  // ...

【讨论】:

【参考方案2】:

super(props); 尚未弃用。弃用消息实际上是由 a bug in React's type definition file 引起的,并且在 @types/react 16.9.51 时已经修复。只需升级软件包即可:

npm install @types/react

【讨论】:

帮我解决了,而其他答案没有 它有效,我建议也添加--save-dev,所以它会转到devDependencies【参考方案3】:

看起来可选的上下文参数已被弃用,因为它引用了遗留的 React 上下文(pre v16.3)。你使用的是什么版本的 React?

https://reactjs.org/docs/legacy-context.html

我没有将 React 与 TypeScript 一起使用。也许 React 映射已经过时了。

【讨论】:

我正在使用 React 16.13.1。让我感到困惑的是,我什至没有使用那个可选参数。 constructor(props, context) 的继承者是什么? 看起来我可以只调用 super() 而不是 super(props)。我从这里得到了这个想法:***.com/questions/30571875/… 这应该没问题,除非你需要在构造函数中使用this.props。后继者在组件外部定义。 reactjs.org/docs/context.html @Steven React' docs 推荐使用 super(props) 所以我认为你可以保持原样。弃用消息实际上是一个错误,有人已经提交了patch 来修复它。【参考方案4】:

我认为这是 jslint 中的一个错误。该代码显然没有使用上下文参数。

【讨论】:

以上是关于为啥react的组件要super的主要内容,如果未能解决你的问题,请参考以下文章

为啥react的组件要super

理解为啥在 React 类组件中不推荐使用 super()

为什么react的组件要super(props)

React,为啥在 ES6 类构造函数中使用 super(props)? [复制]

为啥我们在 React 中创建类组件时要扩展 React.Component?

React Prop 渲染为对象 - 不明白为啥