Javascript React子级调用父级方法Can';t访问状态

Javascript React子级调用父级方法Can';t访问状态,javascript,reactjs,Javascript,Reactjs,我有3个嵌套的组件App->GameList->GameItem 我在App(parent)组件上有一个方法,它通过GameItem(child)组件中的onClick事件获取调用 单击GameItem组件时,它将触发App组件方法以访问App组件中的状态 然而,当我试图访问statethis.state.gamesVM时,我得到一个 未捕获类型错误:无法读取null的属性“gamesVM” 应用程序组件 export default class App extends React.Compo

我有3个嵌套的组件
App->GameList->GameItem

我在
App(parent)
组件上有一个方法,它通过
GameItem(child)
组件中的
onClick
事件获取调用

单击
GameItem
组件时,它将触发
App
组件方法以访问
App
组件中的状态

然而,当我试图访问state
this.state.gamesVM
时,我得到一个

未捕获类型错误:无法读取null的属性“gamesVM”

应用程序组件

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>
    );
  }
}
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>
    )
  }
}
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>
    )
  }
}
导出默认类App扩展React.Component{
状态={
用户ID:3,
gamesVM:[],
}
componentDidMount(){
const pGames=getGames();
const pPicks=getPicks();
const pTeams=getTeams();
承诺。所有([pGames、pPicks、pTeams])
。然后(有效载荷=>{
const gamesVM=this.getGamesVM(有效载荷);
this.setState({gamesVM});
});
}
getGamesVM(有效载荷){
//…获取和映射gamesVM的代码
}
TeamPick(团队、客场、主场){//从子组件调用
console.log(this.state.gamesVM);//未捕获类型错误:无法读取null的属性“gamesVM”
console.log(this.state.userId);//未捕获类型错误:无法读取null的属性“userId”
// ...
console.log(this.state.anything);//未捕获类型错误:无法读取null的属性'anything'
}
render(){
返回(
);
}
}

游戏列表组件

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>
    );
  }
}
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>
    )
  }
}
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>
    )
  }
}
导出默认类游戏列表扩展React.Component{
render(){
返回(
{this.props.gamesVM.map(游戏=>
)}
)
}
}

游戏项目组件

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>
    );
  }
}
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>
    )
  }
}
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>
    )
  }
}
导出默认类GameItem扩展React.Component{
render(){
let-awayPickCheckbox=null;
如果(!this.props.isGameStarted){
awayPickCheckbox=
  • {this.props.awayTeam}
  • ; }否则{ awayPickCheckbox=
  • {this.props.awayTeam}
  • } 返回(
      {awayPickCheckbox}
    ) } }
    您需要使用
    this
    绑定方法。如果忘记绑定
    this.teampick
    并传递,
    在实际调用函数时,this
    将被取消定义

    在构造函数functin中

    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
      }
    
    或者

    render(){
    返回(
    );
    }
    }
    
    es6类中的函数不会自动绑定

    您可以将它们定义为属性和匿名函数,如下所示:

    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
      }
    

    我认为您必须删除绑定函数

     <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)}
                >
    
    
    
    这样做时,我遇到一个语法错误
    语法错误:意外标记(278:5)
    您的编辑答案有效。你能澄清一下这个在
    App-
    中指的是什么,以及它在
    GameItem-onClick={this.props.teampicket.bind(this'away',this.props.id+this.props.awayTeam,this.props.id+this.props.homeTeam)中指的是什么吗?
    @locnguyen参考这个文档:。你会有更好的理解。