2017-03-12 9 views
0

私はReactクラスをES5からES6にリファクタリングしましたが、this.state.dispatch(logIn(this.state.logIn))を呼び出すボタンをクリックすると、行頭の最初のthisがnullになります。超奇妙な。ここでこれは、Reactクラスの関数ではnullです

は私のクラスです:ボタンでログをクリック

class Home extends Component { 
    constructor(props) { 
     super(props); 

     this.state = { 
      panelIsOpen: false, 
      registration: {}, 
      login: {}, 
     }; 
    } 

    signUp() { 
     this.props.dispatch(signUp(this.state.registration)); 

     this.setState({ 
      registration: {}, 
     }); 
    } 

    logIn() { 
     debugger; // this is `null here` 
     this.props.dispatch(logIn(this.state.login)); 

     this.setState({ 
      login: {}, 
     }); 
    } 

    togglePanel(e) { 
     this.setState({ panelIsOpen: !this.state.panelIsOpen}); 
    } 

    render() { 
     const {elements} = this.props; 
     const {registration, login} = this.state; 

     return (
      // some stuff 
     ); 
    } 
}; 

Home.propTypes = { 
    elements: React.PropTypes.array, 
    dispatch: React.PropTypes.func, 
    user: React.PropTypes.object, 
}; 

const mapStateToProps = ({elements, auth}) => { 
    return { 
     elements: getElementsByKeyName(elements, 'visibleElements'), 
     user: getLoggedInUser(auth), 
    }; 
}; 

Home = DragDropContext(HTML5Backend)(Home); 
export default connect(mapStateToProps)(Home); 

は、ログイン機能を呼び出しますが、ここにいくつかの理由で、thisは、ルックを取るためnull

おかげで

答えて

5

はないリアクトです標準的なReactライフサイクルの一部でない限り、ES6クラスに追加されるメソッドのコンテキストをバインドします(componentWillReceivePropscomponentDidMount、など)。

は、これが意味することは、あなたが手動であなたのsignUplogIntogglePanel方法のためthisの値をバインドするか、あるいは親のコンテキストを継承し、矢印の機能、としてそれらを宣言する必要があるということです。参考

constructor(props) { 
    super(props); 
    this.signUp = this.signUp.bind(this); 
    this.logIn = this.logIn.bind(this); 
    this.togglePanel = this.togglePanel.bind(this); 

    this.state = { 
    panelIsOpen: false, 
    registration: {}, 
    login: {}, 
    } 

又は

signUp =() => { 
    this.props.dispatch(signUp(this.state.registration)); 

    this.setState({ 
    registration: {}, 
    }); 
} 

// the same for logIn and togglePanel 

the docsを参照。

+0

は、私は私がそれを取っていたと思います:コンストラクタでそれらをバインドする必要はありません -

constructor(props) { super(props); this.state = { panelIsOpen: false, registration: {}, login: {}, }; this.signUp = this.signUp.bind(this); this.signUp = this.logIn.bind(this); this.togglePannel = this.togglePannel.bind(this); } 
  • あなたのための現在のスコープにバインドします矢印の機能として、あなたのメソッドを定義します。私が 'createClass'を使っているときに与えられたものです。ありがとう! –

  • 1

    これは、ES6でどのように機能がバインドされているかに関係しています。メソッドを別のコンポーネントに渡している場合、そのコンポーネントが実行されたコンテキストは、(最初​​にバインドしない限り)正しいコンテキストであるとは限りません。ここではその上に長いが、興味深いの読み取りとの記事です:コンストラクタでこれに

    1. (かなり共通/人気)バインドあなたの方法:要するにhttp://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/

      が、あなたはカップルのオプションがあります。すべてのメソッドをバインドする必要はなく、使用方法に依存します。

      class Home extends Component { 
          // ... 
      
          signUp =() => { 
           this.props.dispatch(signUp(this.state.registration)); 
      
           this.setState({ 
            registration: {}, 
           }); 
          } 
      
          // ... 
      } 
      
    +0

    Jamesに感謝します。ニース・プン;) –

    関連する問題