Reputation: 312
I am facing an issue and don't understand why my code doesn't work.
The point :
Here is the code for Key.js :
const Key = ({ letter, onClick }) => (
<button className={`keyboardLetter`} onClick={() => onClick(letter)} >{ letter }</button>
);
export default Key;
Here is the code rendering it in App.js :
render() {
return (
<div className="keyboard">
{
// LETTERS is an array containing letters from A to Z
LETTERS.map((letter, index) => (
<Key letter={letter} onClick={this.handleKeyClick} key={index} />
))
}
</div>
)
}
Here is the code for the handleKeyClick method :
// Arrow function for binding
handleKeyClick = (letter) => {
// Here I do several operations for my app to work (setState() etc…)
// I can get the letter I clicked by doing :
console.log(letter);
// The point is I can not retrieve the HTML button element clicked, even with :
console.log(letter.target) // returns undefined
// letter.currentTarget, .parentElement or .parentNode also return undefined
};
I have found a workaround, but if I understood correctly is not the best practice to do. It is changing the onClick event on Key.js SFC to this :
onClick={(event) => onClick(letter, event)}
And then use the event property like so in my method :
handleKeyClick = (letter, event) => { }
With this I can get the button element clicked with event.target, but if I understood correctly would cause less performances and seems more trouble and code to get my App working as wanted.
Thank you very much for your time and help.
Tom
Upvotes: 1
Views: 4736
Reputation: 75
const Key = ({ letter, onClick }) => (
<button className={`keyboardLetter`} onClick={(e) => onClick(e, letter)} >{letter}</button>
);
handleKeyClick = (e, letter) => {
debugger
//e -- event
//letter
}
render() {
let LETTERS = ["a", "b"]
return (
<Fragment>
<div className="keyboard">
{
LETTERS.map((letter, index) => (
<Key letter={letter} onClick={(e) => { this.handleKeyClick(e, letter) }} key={index} />
))
}
</div>
</Fragment>
);
}
Upvotes: 0
Reputation: 7492
There is no need to access your button's element in this case.
You can achieve it by giving your function multiple parameters groups so that you preconfigure it:
handleKeyClick = (letter) => (ev) => {
console.log(letter);
console.log(ev);
};
This function will need to be called twice to execute what's inside. The first call will set the letter
parameter and return a function that only requires the event.
You can now call the function within the click function itself:
LETTERS.map((letter, index) => (
<Key letter={letter} onClick={this.handleKeyClick(letter)} key={index} />
))
The handler won't be called directly, this parameter only sets the letter variable in the function.
Here is how you can get the event information, by making the event directly to your function:
<button className={`keyboardLetter`} onClick={onClick} >{ letter }</button>
You were previously ignoring the event returned by onClick
which is in its first parameter : onClick={(/* event variable missing */) => onClick(letter)}
Upvotes: 1
Reputation: 166
In your Key.js
file, you need to send the event if you want to access it later.
const Key = ({ letter, onClick }) => (
<button className={`keyboardLetter`} onClick={(e) => onClick(e,letter)} >{ letter }</button>
);
Add both event and letter arguments to your handleKeyClick
function
const handleKeyClick = (e, letter) => {
console.log(letter);
console.log(e.target);
};
Pass click event
and letter
to your handleKeyClick
function
LETTERS.map((letter, index) => (
<Key letter={letter} onClick={(e, letter) => this.handleKeyClick(e, letter)} key={index} />
))
Upvotes: 0