Comme expliqué dans le titre, l'erreur se produit L'auditeur onClick attendu est une fonction, mais un objet de type
Mais je suis incapable de comprendre pourquoi cela ne marche pas ... autant que je sache, l'écouteur onClick IS est une fonction.
Voici le composant CharacterList d'où provient l'erreur
import React,{Component} from 'react';
import {connect} from 'react-redux';
import {addCharacterById} from '../actions';
import {bindActionCreators} from 'redux';
class CharacterList extends Component{
render(){
//console.log('name : ',this.props.characters[2].name);
return(
<div>
<h3>Characters</h3>
<ul>
{this.props.characters.map((character)=>{
return(<li key={character.id}>{character.name}
<div
onClick={this.props.addCharacterById(character.id)}
>+</div>
</li>);
})}
</ul>
</div>
)
}
}
function mapStateToProps(state){
return {
characters:state
}
}
export default connect(mapStateToProps,{addCharacterById})(CharacterList);
Et voici le créateur d'action
export const ADD_CHARACTER='ADD_CHARACTER';
export function addCharacterById(id){
var action ={
type:ADD_CHARACTER,
id
}
return action;
}
Alors, qu'en pensez-vous? Quel est le problème ici?
Le problème est que vous appelez la fonction immédiatement et qu'il ne reste que la valeur de retour, qui peut ne pas être une fonction!
Au lieu de cela, vous pouvez insérer cet appel de fonction dans une fonction de flèche pour résoudre votre problème. Il appellera la fonction interne une fois que vous aurez cliqué:
import React,{Component} from 'react';
import {connect} from 'react-redux';
import {addCharacterById} from '../actions';
import {bindActionCreators} from 'redux';
class CharacterList extends Component{
render(){
//console.log('name : ',this.props.characters[2].name);
return(
<div>
<h3>Characters</h3>
<ul>
{this.props.characters.map((character)=>{
return(<li key={character.id}>{character.name}
<div
onClick={() => this.props.addCharacterById(character.id)}
>+</div>
</li>);
})}
</ul>
</div>
)
}
}
function mapStateToProps(state){
return {
characters:state
}
}
export default connect(mapStateToProps,{addCharacterById})(CharacterList);
Il y a différentes façons de le faire, vous pouvez par exemple lier le paramètre à la fonction, par exemple:
{this.props.characters.map((character)=>{
return(<li key={character.id}>{character.name}
<div
onClick={this.props.addCharacterById.bind(null, character.id)}
>+</div>
</li>);
})}
Juste partagé à titre d'exemple, pour que vous compreniez ce qui se passe et pourquoi la première approche est plus lisible. Vous voudrez peut-être comprendre pourquoi .bind dans le rendu est une mauvaise pratique en lisant l'article https://ryanfunduk.com/articles/never-bind-in-render/
Il y a des choses que vous devez changer si vous voulez avoir de bonnes pratiques.
Premièrement, ajoutez la fonction mapDispatchToProps
.
import { bindActionCreators } from 'redux';
...
function mapDispatchToProps(dispatch) {
return {
addCharacterById: bindActionCreators(addCharacterById, dispatch)
};
}
Deuxièmement, le gestionnaire d'événement pourrait être:
onClick={() => this.props.addCharacterById(character.id)}
Troisièmement, exportez votre composant:
export default connect(mapStateToProps, mapDispatchToProps)(CharacterList);