I'm new in react, and i'm can't understand why simple button is not working.
export default class PlayerList extends Component {
constructor(props) {
super(props)
this.state = {
players: [],
convocPlayers: []
}
this.sendConvoc = this.sendConvoc.bind(this)
}
async sendConvoc() {
try {
let data = this.state.convocPlayers;
await axios.post('/players/convoc', {
players: data
});
} catch (error) {
alert(error)
}
}
render() {
return (
<div>
<PlayerForm addPlayer={(user) => this.addPlayer(user)}></PlayerForm>
</div>
<div className="flex items-center justify-between mt-8">
<span className="text-3xl">Liste des joueurs</span>
<PrimaryButton onClick={() => this.sendConvoc}>Envoyer la convocation</PrimaryButton>
</div>
)
}
}
My PrimaryButton component :
export default class PrimaryButton extends React.Component {
render () {
return (
<button type={this.props.type} onClick={() => this.onClick} className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
{this.props.children}
</button>
)
}
onClick() {
var clickFunction = this.props.onClick || null;
if (clickFunction) {
clickFunction()
}
}
}
The sendConvoc function is never triggered when I click on the "PrimaryButton", if anyone has a solution, thank you in advance
You should change the onClick function to either onClick={() => this.onClick()} or just onClick={this.onClick}
We must understand why your function is not triggered. When we specify an event ie onClick, React expects us to pass a function not call the function.
✅ Correct - Passing a function
<PrimaryButton onClick={this.sendConvoc}>
// passing an inline function
<PrimaryButton onClick={() => this.sendConvoc()}>
<PrimaryButton onClick={() => alert('hello')}>
For inline function, notice that we need to call the function inside, otherwise the inline function will return the function definition (not calling the function).
❌ Incorrect - calling a function
<PrimaryButton onClick={this.sendConvoc()}>
<PrimaryButton onClick={alert('hello')}>
For your case, the solution in PrimaryButton component is to call the function inside the inline function. Also, we probably don't need an inline function there which is a simpler solution.
// BEFORE
// the issue here is we forgot to call `this.onClick`, we return function definition of `this.onClick` here.
<button type={this.props.type} onClick={() => this.onClick}
// AFTER
<button type={this.props.type} onClick={() => this.onClick()}
// or
<button type={this.props.type} onClick={this.onClick} // simpler
In PlayerList component
// BEFORE
<PrimaryButton onClick={() => this.sendConvoc}>
// AFTER
<PrimaryButton onClick={() => this.sendConvoc()}>
// or
<PrimaryButton onClick={this.sendConvoc}>