javascript reactjs frontend

javascript - Reaccionar ''no se puede leer la propiedad de indefinido'' cuando se usa el mapa



reactjs frontend (2)

No ha realizado el enlace para la función de mapa donde está utilizando onScoreChange = {this.onPlayerScoreChange} ,

puede usar las funciones de enlace o flecha para el enlace

PS Binding es necesario porque el contexto de la función de mapa es diferente del contexto React Component y, por this tanto, this dentro de esta función no se referirá a React Components y, por lo tanto, no puede acceder a esas propiedades de la clase React Component.

Con la función de flecha:

{this.state.initialPlayers.map((player, index)=> { return( <Player name = {player.name} score = {player.score} key = {player.id} index = {index} onScoreChange = {this.onPlayerScoreChange} /> ) })}

Con enlace

{this.state.initialPlayers.map(function(player, index) { return( <Player name = {player.name} score = {player.score} key = {player.id} index = {index} onScoreChange = {this.onPlayerScoreChange} /> ) }.bind(this))}

Estoy haciendo una aplicación React muy básica de teamtreehouse.com, y constantemente encuentro

"TypeError: no se puede leer la propiedad ''onPlayerScoreChange'' de undefined"

a pesar de que estoy vinculando mis funciones correctamente (creo)

''onPlayerScoreChange'' es un método en el componente Grandparent que se ejecuta cuando un usuario presiona un botón ''+'' o ''-'' para cambiar la puntuación de un jugador.

Sería realmente útil si alguien pudiera explicar lo que está mal, porque creo que estoy configurando this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this) en el constructor del bisabuelo.

Componente principal:

class App extends React.Component { constructor(props) { super(props); this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this) this.state = { initialPlayers: props.initialPlayers, }; } onPlayerScoreChange(delta, index) { this.setState((prevState, props) => { return {initialPlayers: this.prevState.initialPlayers[index].score += delta} }) } render() { return( <div className = "scoreboard"> <Header title = {this.props.title}/> <div className = "players"> {this.state.initialPlayers.map(function(player, index) { return( <Player name = {player.name} score = {player.score} key = {player.id} index = {index} onScoreChange = {this.onPlayerScoreChange} /> ) })} </div> </div> ) }}

(El componente tiene accesorios predeterminados para el título)

Componente hijo:

class Player extends React.Component { render() { return( <div className = "player"> <div className = "player-name"> {this.props.name} </div> <div className = "player-score"> <Counter score = {this.props.score} onChange = {this.props.onScoreChange} index = {this.props.index}/> </div> </div> ) }}

Componente nieto:

class Counter extends React.Component { constructor(props) { super(props) this.handleDecrement = this.handleDecrement.bind(this) this.handleIncrement = this.handleIncrement.bind(this) } handleDecrement() { this.props.onChange(-1, this.props.index) } handleIncrement() { this.props.onChange(1, this.props.index) } render() { return( <div className = "counter"> <button className = "counter-action decrement" onClick = {this.handleDecrement}> - </button> <div className = "counter-score"> {this.props.score} </div> <button className = "counter-action increment" onClick = {this.handleIncrement}> + </button> </div> )}}

¡Gracias!


También se puede hacer pasando un segundo argumento, ya que esto para mapear la función, ya que el evento onClick usa esto local de la función de mapa que no está definida aquí y esto actualmente se refiere al objeto global.

{this.state.initialPlayers.map(function(player, index) { return( <Player name = {player.name} score = {player.score} key = {player.id} index = {index} onScoreChange = {this.onPlayerScoreChange} /> ) }),this}