2017-04-07 148 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)} 
      >