Reputation: 31
UPDATE: My code checked out just fine. The issue was that a stopPropagation() was called in a separate Javascript library that prevented my onClicks from working.
--
I have a "MenuLink" react component in which I've added an onClick listener to an 'a' tag. The "MenuLink" component is imported from a "MenuItem" component which is imported from a "MainMenu" component (see below).
When I click on link generated from MenuLink, nothing happens. No errors, no nothing. I would expect to see "handleClick" in my console and for the link to be prevented from executing.
MenuLink.js
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
export default MenuLink;
MenuItem.js
import MenuLink from './MenuLink.js';
class MenuItem extends React.Component {
constructor(props) {
super(props);
this.state = props.item;
}
render(key) {
const item = this.state;
return(
<li
key={key}
>
<MenuLink
link={item}
/>
</li>
);
}
}
export default MenuItem;
MainMenu.js
import MenuItem from '../components/MenuItem.js';
class MainMenu extends React.Component {
state = {
menu: []
}
render() {
return(
<ul className="menu">
{this.state.menu.map(function(menuItem, i) {
return(
<MenuItem key={i} item={menuItem} />
)
})}
</ul>
);
}
componentDidMount() {
fetch('/api/menu_items/main')
.then(res => res.json())
.then((data) => {
this.setState({ menu: data })
})
.catch(console.log)
}
}
export default MainMenu;
Upvotes: 0
Views: 967
Reputation: 4692
This approach should work
class MenuLink extends React.Component {
constructor(props) {
super(props);
//this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick = e => {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
export default MenuLink;
Upvotes: 0
Reputation: 14395
The below snippet shows that it does work as expected. No changes were made.
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = props.link;
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state;
return (
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
);
}
}
class MenuItem extends React.Component {
constructor(props) {
super(props);
this.state = props.item;
}
render(key) {
const item = this.state;
console.log(key) // Undefined. Don't do this
return(
<li
key={key}
>
<MenuLink
link={item}
/>
</li>
);
}
}
class MainMenu extends React.Component {
state = {
menu: [{
alias: 'test',
title: 'test'
},
{
alias: 'test2',
title: 'test2'
}]
}
render() {
return(
<ul className="menu">
{this.state.menu.map(function(menuItem, i) {
return(
<MenuItem key={i} item={menuItem} />
)
})}
</ul>
);
}
}
ReactDOM.render(<MainMenu />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
Upvotes: 1
Reputation: 5862
Please check this example:
import React from "react";
class MenuLink extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
// this.state = props.link;
this.state = {
link: {alias: "http://www.google.com", title: 'Google'}
}
}
handleClick(e) {
console.log("handleClick");
e.preventDefault();
}
render() {
const link = this.state.link;
return (
<div>
<a
href={link.alias}
onClick={this.handleClick}
>
{link.title}
</a>
</div>
);
}
}
export default MenuLink;
Upvotes: 0