React,ES6-getInitialState在普通的JavaScript类上定义


115

我具有以下组件(radioOther.jsx):

 'use strict';

 //module.exports = <-- omitted in update

   class RadioOther extends React.Component {

     // omitted in update 
     // getInitialState() {
     //    propTypes: {
     //        name: React.PropTypes.string.isRequired
     //    }
     //    return {
     //       otherChecked: false
     //   }
     // }

     componentDidUpdate(prevProps, prevState) {
         var otherRadBtn = this.refs.otherRadBtn.getDOMNode();

         if (prevState.otherChecked !== otherRadBtn.checked) {
             console.log('Other radio btn clicked.')
             this.setState({
                 otherChecked: otherRadBtn.checked,
             });
         }
     }

     onRadChange(e) {
         var input = e.target;
         this.setState({
             otherChecked: input.checked
         });
     }

     render() {
         return (
             <div>
                 <p className="form-group radio">
                     <label>
                         <input type="radio"
                                ref="otherRadBtn"
                                onChange={this.onRadChange}
                                name={this.props.name}
                                value="other"/>
                         Other
                     </label>
                     {this.state.otherChecked ?
                         (<label className="form-inline">
                             Please Specify:
                             <input
                                 placeholder="Please Specify"
                                 type="text"
                                 name="referrer_other"
                                 />
                         </label>)
                         :
                         ('')
                     }
                 </p>
             </div>
         )
     }
 };

在使用ECMAScript6之前,一切都很好,现在出现1个错误,1个警告,并且我有一个后续问题:

错误:未捕获的TypeError:无法读取null的属性“ otherChecked”

警告: getInitialState是在RadioOther(一个普通的JavaScript类)上定义的。仅使用React.createClass创建的类支持此功能。您是要定义状态属性吗?


  1. 谁能看到错误在哪里,我知道这是由于DOM中的条件语句引起的,但显然我没有正确声明其初始值?

  2. 我应该让getInitialState静态

  3. 如果getInitialState不正确,在什么地方声明我的原型?

更新:

   RadioOther.propTypes = {
       name: React.PropTypes.string,
       other: React.PropTypes.bool,
       options: React.PropTypes.array }

   module.exports = RadioOther;

@ssorallen,此代码:

     constructor(props) {
         this.state = {
             otherChecked: false,
         };
     }

产生"Uncaught ReferenceError: this is not defined",而在下面纠正

     constructor(props) {
     super(props);
         this.state = {
             otherChecked: false,
         };
     }

但是现在,单击另一个按钮现在会产生错误:

Uncaught TypeError: Cannot read property 'props' of undefined


1
对于ES6类另一个变化是,方法不是“自动绑定”的情况下,当你通过像功能意味着onChange={this.onRadChange}this当不参照实例onRadChange被调用。您需要在其中绑定回调render或在构造函数中进行回调:onChange={this.onRadChange.bind(this)}
罗斯·艾伦

Answers:


239
  • getInitialState在ES6类中不使用。而是this.state在构造函数中分配。
  • propTypes 应为静态类变量或分配给该类,不应将其分配给组件实例。
  • 成员方法在ES6类中不是“自动绑定”的。对于用作回调的方法,请使用类属性初始化程序或在构造函数中分配绑定的实例。
export default class RadioOther extends React.Component {

  static propTypes = {
    name: React.PropTypes.string.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      otherChecked: false,
    };
  }

  // Class property initializer. `this` will be the instance when
  // the function is called.
  onRadChange = () => {
    ...
  };

  ...

}

在React的文档中了解有关ES6类的更多信息:将函数转换为类


一年过去了,现在您可能会发现:Uncaught TypeError: Cannot read property 'bind' of undefined错误任何想法?
Jamie Hutber '16

@JamieHutber您能用您的代码创建一个新问题吗?如果方法是在类上定义的,我不知道为什么会出现该错误。
罗斯·艾伦

感谢您的建议,@ KennethWorden。我为React文档打开了一个问题:github.com/facebook/react/issues/7746
Ross Allen

“将它们绑定到位”是否意味着使用上面显示的箭头功能?当然可以。哦,javascript!
jomofrodo

@jomofrodo这是模棱两可的,感谢您指出。我的意思是render您可以做类似的事情onClick={this.doFoo.bind(this)},但是我故意不将其包含在代码中,因为这是绑定效率最低的方法,因为它render可能经常被调用,并且每次调用都会创建新的函数。我将从答案中删除该语言。
罗斯·艾伦

4

添加到罗斯的答案。

您还可以在onChange属性上使用新的ES6箭头功能

它在功能上等同this.onRadChange = this.onRadChange.bind(this);于在构造函数中定义,但在我看来更为简洁。

在您的情况下,单选按钮将如下所示。

<input type="radio"
       ref="otherRadBtn"
       onChange={(e)=> this.onRadChange(e)}
       name={this.props.name}
       value="other"/>

更新资料

这种“更简洁”的方法比@Ross Allen的答案中提到的选项效率低,因为每次render()调用该方法时都会生成一个新函数。


1
该解决方案在功能上是正确的,但是它在每次调用时都会创建一个新的Function render(可以多次调用)。通过在构造函数中使用类属性初始化器或绑定,在构造组件时仅创建一个新的绑定Function,而在期间不创建新的Function render
罗斯·艾伦

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.