2017-04-07 119 views
1

我有嵌套App->GameList->GameItem阵营儿童调用父方法无法访问状态

我有通过onClick事件在GameItem(child)组件

当得到调用App(parent)组件上的方法3个组件GameItem组件被点击它触发App组件方法来访问App组件中的状态。

然而,当我尝试访问状态this.state.gamesVM我得到一个

Uncaught TypeError: Cannot read property 'gamesVM' of null

APP COMPONENT

export default class App extends React.Component { 

    state = { 
    userId: 3, 
    gamesVM: [], 
    } 

    componentDidMount() { 
    const pGames = getGames(); 
    const pPicks = getPicks(); 
    const pTeams = getTeams(); 

    Promise.all([pGames, pPicks, pTeams]) 
     .then(payload => { 
     const gamesVM = this.getGamesVM(payload); 
     this.setState({gamesVM}); 
     }); 
    } 

    getGamesVM(payload) { 
    // ... code to get and map gamesVM 
    } 

    teamPicked(team, away, home) { // gets called from child component 
    console.log(this.state.gamesVM); // Uncaught TypeError: Cannot read property 'gamesVM' of null 
    console.log(this.state.userId); // Uncaught TypeError: Cannot read property 'userId' of null 
    // ... 
    console.log(this.state.anything); // Uncaught TypeError: Cannot read property 'anything' of null 
    } 

    render() { 
    return (
     <div className="App"> 
     <form onSubmit={this.handleSubmit}> 
      <GameList 
      gamesVM={this.state.gamesVM} 
      teamPicked={this.teamPicked} 
      /> 
      <input type="submit" value="Save" /> 
     </form> 
     </div> 
    ); 
    } 
} 

游戏列表COMPONENT

export default class GameList extends React.Component { 
    render() { 
    return (
     <div className='matchups'> 
     {this.props.gamesVM.map(game => 
      <GameItem 
      teamPicked={this.props.teamPicked} 
      key={game.id} 
      {...game} 
      /> 
     )} 
     </div> 
    ) 
    } 
} 

GAMEITEM COMPONENT

export default class GameItem extends React.Component { 

    render() { 

    let awayPickCheckbox = null; 

    if (!this.props.isGameStarted) { 

     awayPickCheckbox = <li> 
      <input type="checkbox" id={this.props.id + this.props.awayTeam} /> 
      <label 
       htmlFor={this.props.id + this.props.awayTeam} 
       onClick={this.props.teamPicked.bind(this, 'away', this.props.id + this.props.awayTeam, this.props.id + this.props.homeTeam)} 
      > 
       {this.props.awayTeam} 
      </label> 
      </li>; 

    } else { 

     awayPickCheckbox = <li> 
      <label>{this.props.awayTeam}</label> 
      </li> 
    } 


    return (
     <div className="single-matchup"> 
     <ul className="away-team clearfix"> 
      {awayPickCheckbox} 
     </ul> 
     </div> 
    ) 
    } 
} 

回答

1

功能不被自动绑定。

你可以将它们定义为性和匿名函数是这样的:

teamPicked = (team, away, home) => { // gets called from child component 
    console.log(this.state.gamesVM); // Uncaught TypeError: Cannot read property 'gamesVM' of null 
    console.log(this.state.userId); // Uncaught TypeError: Cannot read property 'userId' of null 
    // ... 
    console.log(this.state.anything); // Uncaught TypeError: Cannot read property 'anything' of null 
    } 
+0

这个答案适合我 – locnguyen

2

您需要this T0绑定方法。如果你忘了绑定this.teamPicked而过,当函数实际上是所谓this是不确定的。 ES6类中

内部构造载体作用,

this.teamPicked = this.teamPicked.bind(this) 


teamPicked(team, away, home) { // gets called from child component 
    console.log(this.state.gamesVM); // Uncaught TypeError: Cannot read property 'gamesVM' of null 
    console.log(this.state.userId); // Uncaught TypeError: Cannot read property 'userId' of null 
    // ... 
    console.log(this.state.anything); // Uncaught TypeError: Cannot read property 'anything' of null 
    } 

OR,

render() { 
    return (
     <div className="App"> 
     <form onSubmit={this.handleSubmit}> 
      <GameList 
      gamesVM={this.state.gamesVM} 
      teamPicked={this.teamPicked.bind(this)} 
      /> 
      <input type="submit" value="Save" /> 
     </form> 
     </div> 
    ); 
    } 
} 
+0

我得到一个语法错误做这种方式'语法错误:意外的令牌(278:5)' – locnguyen

+0

@locnguyen我的错。我更新了我的答案。 – Ved

+0

您的编辑答案有效。你能澄清'this'在'App- '中引用了什么,它在GameItem中引用了什么 - onClick = {this.props.teamPicked.bind this,'away',this.props.id + this.props.awayTeam,this.props.id + this.props.homeTeam)}' – locnguyen

0

我认为你必须删除绑定功能。

<label 
        htmlFor={this.props.id + this.props.awayTeam} 
        onClick={this.props.teamPicked('away', this.props.id + this.props.awayTeam, this.props.id + this.props.homeTeam)} 
      >