我们先把菜鸟教程的一段代码拿过来分析一下。下面这段代码是用了将生命周期方法添加到类中实现时钟效果。
// 将生命周期方法添加到类中 class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()};//初始化 } //开始 componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } //销毁 componentWillUnmount() { clearInterval(this.timerID); } //重新改变date值 tick() { this.setState({ date: new Date() }); } //注册组件 render() { return ( <div> <h1>Hello, world!</h1> <h2>现在是 {this.state.date.toLocaleTimeString()}.</h2> </div> ); } } //···································· //挂载到实例 ReactDOM.render( <Clock />, document.getElementById('example') );
好,下面我们就再写一段原生js实现上述效果,对比一下。
function timejs () { this.timer = null; var time1= new Date(); var time2=time1.toLocaleTimeString() document.getElementById("time").innerHTML = time2 //这里的id为time我这里没写,自己写上即可<div id='time'></div> } var timer=setInterval(timejs,1000);
嗯,我们可以看到原生js代码量比React少得多。 下面我们为了方便起见。将React中的代码写为A,将原生JS中的代码写为B。 B中的timejs()相当于A中的tick(),不同的是A需要初始化,所以A中有 this.state = {date: new Date()}; 这时你会发现super(props)是什么鬼?我注释掉行不行?答案是不行的。你会看到下面这段鲜红的BUG。
错误的含义是this之前不能没有super(props) 那么super到底是什么呢
super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
简言之,如果你想在constructor中使用this,就必须用super(props), 那么在这里可以不传props吗?答案是最好写。
虽然 React 会在组件实例化的时候设置一遍 props(当React添加对类的支持时,它不仅仅增加了对ES6类的支持。目标是尽可能支持广泛的类抽象。目前尚不清楚ClojureScript,CoffeeScript,ES6,Fable,Scala.js,TypeScript或其他解决方案在定义组件方面的成功程度。所以React故意不关心是否需要调用super - 即使是ES6
类。),但在 super 调用一直到构造函数结束之前,this.props 依然是未定义的。 执行 super(props) 可以使基类 React.Component 初始化 this.props。 好,我把代码改了改
// 将生命周期方法添加到类中 class Clock extends React.Component { constructor(props) { super(props); console.log(this.props) this.state = { date: new Date(), tit:'success' };//初始化 } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>Hello, world!</h1> <h2>现在是 {this.state.date.toLocaleTimeString()}.</h2> <button>{this.props.val}</button> </div> ); } } ReactDOM.render( <Clock val='success'/>, document.getElementById('example') );
总之,你不管用不用this.props。最好在使用constructor构造函数初始化时都用super(props)
如果需要访问this就设置constructor
如果没用到constructor,是可以不写的;React会默认添加一个空的constructor。
如果你用到了constructor就必须写super(),是用来初始化this的,可以绑定事件到this上;
如果你在constructor中要使用this.props,就必须给super加参数:super(props);
无论有没有constructor,在render中this.props都是可以使用的,这是React自动附带的。