Reputation: 223
First, Sorry for my Bad English. I want to make a category tree component and blew is my rendering code.
class tree extends Component {
constructor(props) {
super(props);
this.state = {
showBig1: false,
showBig2: false,
showSmall1: false,
showSmall2: false,
current: 'fake',
fake: false
};
}
toggleBigMenu = (type, current_now) => {
this.state = {
[current_now]: false,
[type]: true,
current: type
}
}
render() {
const {showBig1, showBig2, showSmall1, showSmall2} = this.state
return (
<div>
<li className={showBig1 ? "on" : "off"} onClick={this.toggleBigMenu("showBig1", current)}>
<Link to="#">
<span>BIG MENU 1</span>
</Link>
</li>
<li className={showBig2 ? "on" : "off"} onClick={this.toggleBigMenu("showBig2", current)}>
<Link to="#">
<span>BIG MENU 2</span>
</Link>
<ul>
<li className={showSmall1 ? "on" : "off"} onClick={this.toggleBigMenu("showSmall1", current)}>
<Link to="#">
<span>SMALL MENU 1</span>
</Link>
</li>
<li className={showSmall2 ? "on" : "off"} onClick={this.toggleBigMenu("showSmall2", current)}>
<Link to="#">
<span>SMALL MENU 2</span>
</Link>
</li>
</ul>
</li>
</div>
)
}
}
and I want to click only one 'li' item at a time. But When I click BIG MENU1, it clicked with BIG MENU 2. And BIG MENU 2's state turn true, but I want to turn BIG MENU 1's state.
I don't know how to solve it.. please anyone help me. Thank you.
Upvotes: 3
Views: 4901
Reputation: 112917
By writing onClick={this.toggleBigMenu("showBig1", current)}
you are invoking this.toggleBigMenu
directly on render. You can create a new function that will be invoked when the event occurs instead.
Instead of passing in current
every time you change menu, you can reset all menus to being false
and just setting the clicked one to true
.
Since you have menus inside other menus, it's also a good idea to call event.stopPropagation()
on the click event so the nested menus have a chance of being selected.
Example
const menus = {
showBig1: false,
showBig2: false,
showSmall1: false,
showSmall2: false
};
class Tree extends React.Component {
state = { ...menus };
toggleMenu = (event, type) => {
event.stopPropagation();
this.setState({
...menus,
[type]: true
});
};
render() {
const { showBig1, showBig2, showSmall1, showSmall2, current } = this.state;
return (
<div>
<li
style={{ backgroundColor: showBig1 ? "green" : "red" }}
onClick={event => this.toggleMenu(event, "showBig1")}
>
<span>BIG MENU 1</span>
</li>
<li
style={{ backgroundColor: showBig2 ? "green" : "red" }}
onClick={event => this.toggleMenu(event, "showBig2")}
>
<span>BIG MENU 2</span>
<ul>
<li
style={{ backgroundColor: showSmall1 ? "green" : "red" }}
onClick={event => this.toggleMenu(event, "showSmall1")}
>
<span>SMALL MENU 1</span>
</li>
<li
style={{ backgroundColor: showSmall2 ? "green" : "red" }}
onClick={event => this.toggleMenu(event, "showSmall2")}
>
<span>SMALL MENU 2</span>
</li>
</ul>
</li>
</div>
);
}
}
ReactDOM.render(<Tree />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Upvotes: 3