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}