【问题标题】:Is constructor needed for a ReactJS component classReactJS 组件类是否需要构造函数
【发布时间】:2016-02-16 19:45:41
【问题描述】:

我在 Typescript 中使用 ReactJS。我需要下面的“构造函数”代码吗?没有它它也能正常工作,我查看了转堆的 JavaScript,它似乎无论如何都会自动添加它。

interface myProps {
   children?: any;
}
class MyButton extends React.Component<myProps, {}> {
    constructor(props: myProps) { //Needed ???
        super(props);
    }

    render() {
        return (<div>
            <button>
                {this.props.children}
            </button>
        </div>);
    } //end render.
} //end class.

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    不,你不需要。

    实际上,您可以将这样的简单组件编写为函数。

    const MyButton = (props) => {
      return (
        <div><button>{props.children}</button></div>
      );
    };
    

    【讨论】:

      【解决方案2】:

      如已接受的答案中所述:

      const MyButton = (props) => {
        return (
          <div><button>{props.children}</button></div>
        );
      };
      

      这可行,但不一样 - 根本不一样。这是在构造一个无状态组件(没有状态,没有生命周期钩子,它只是一个普通函数,只返回 JSX 或“渲染”函数的一部分)。

      如果您需要状态或生命周期挂钩,则必须从 React.Component 扩展 - 就像问题中已经完成的那样。

      要真正回答您的问题 - 是的,需要构造函数。那是因为您正在扩展一个现有类,该类已经在请求必须在构造上提供的初始属性(“props”) -> 因为它是一个反应类,反应将在内部调用类似

      new MyButton(props);
      

      他会总是将 props 对象提供给实例化的组件。现在,通过扩展这个现有的 React 组件类,你必须达到同样的效果——否则你最终会错过你的“道具”对象。为了使它成为可能,仍然可以将“道具”传递给您新定义的组件,您还必须在构造函数中定义道具,因此您必须这样写:

      constructor(props: myProps) { .. }
      

      否则,当您调用“new MyButton(props)”时,您将无法传递任何内容 -> 好吧,这不会排除或带来错误,但“props”在您的进一步代码中将只是“null”我的按钮”。

      最后但同样重要的是 - 您必须在扩展版本中调用“超级”。

      super(props);
      

      否则,您不会将给定的“prop”对象传递给您从中扩展的基本类。在这里,没有它也可以工作,但是 - 那么“props”在“React.Component”本身的任何代码中都是“null”。

      所以,是的,它是必需的!

      基本上,您可以通过简单地使用调试器自己回答这个问题 - 只需打开您的 web-dev 工具,跳转到您的组件代码,在您的构造函数中设置一个断点,然后仔细观察正在发生的事情和传递的内容;)然后,一次删除构造函数中的属性..并删除一次超级调用...它将如何除/分解? ;)

      更新:

      在创建新的 React 组件时,您总是可以问自己的另一个问题:我需要状态吗?我需要生命周期钩子吗?

      如果其中之一是肯定的,那么您将不得不从 React.Component 扩展 - 因为只有基本类才能为您提供这种糖。但可以说,不,我不需要任何这些 - 总是使用 StatelessComponent:

      const MyComp = (props) => (
        <div></div>
      )
      

      并尽量避免局部组件状态 - 你可以通过 react-redux 和选择器使用一个全局状态做得更好;)

      【讨论】:

      • 谢谢。我会保留构造函数。
      • 我认为这个答案并不准确。完全可以不使用构造函数并定义状态和访问生命周期钩子。
      【解决方案3】:

      在反应中不再需要构造函数和超级。可以在没有构造函数的情况下定义状态,并且生命周期挂钩也可以正常工作。这是 Babel 以这种方式转换组件的结果:http://2ality.com/2017/07/class-fields.html

      在传统的 ES6 中,目前情况并非如此。

      【讨论】:

      【解决方案4】:

      如今,只有当你必须使用 props 的状态初始化组件时才需要构造函数。

      import React from 'react'
      
      class AChildComponent extends React.Component {
        constructor(props){
          super(props)
          this.state = {
            myState: props.myStateFromProps
          }
        }
      
        render(){
          return(
            <div>
              <p>{this.state.myState}</p>
            </div>
          )
        }
      }
      
      export default AChildComponent
      
      

      【讨论】:

        猜你喜欢
        • 2014-04-23
        • 2021-05-25
        • 2013-10-25
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多