这个问题很简单,没有专门与导航栏相连,这只是一个很好的例子。
我想使用'active'类创建带有活动标签突出显示的简单导航栏。目前,我有两个组件:NavBar和NavItem。在选项卡上单击时,我要使其处于活动状态,并确保所有其他状态都变为非活动状态。
最简单的解决方案是什么?如何将NavBar中的多个NavItem重置为默认的非活动状态,而无需单击任何状态?
NavBar.js
import React from 'react';
import NavItem from './NavItem';
export default class NavBar extends React.Component {
constructor() {
super();
this.menuItems = [
{ name: 'HOME', url: '#' },
{ name: 'NEWS', url: '#' },
{ name: 'CONTACT', url: '#' }
];
}
render() {
return (
<nav>
<ul>
CHOOSE:
{this.menuItems.map( (item,i) => <NavItem key={i} data={item} /> )}
</ul>
</nav>
);
}
}
NavItem.js
import React from 'react';
export default class NavItem extends React.Component {
constructor() {
super();
this.state = {
active: false
}
}
handleOnClick() {
this.setState({active: !this.state.active});
}
render() {
let item = this.props.data;
return <li><a href={item.url} className={this.state.active ? 'active' : ''} onClick={ (e) => this.handleOnClick(e) }>{item.name}</a></li>;
}
}
答案 0 :(得分:0)
我看不到将列表项放在其他组件中的好处。实际上,由于每个项目都是一个单独的组件,您最终将在一个列表项上设置active
类。
最简单的方法是将列表放在同一组件中,并在click函数中传递索引。
{this.menuItems.map((item,i) => <li><a href={item.url} className={this.state.activeItem == i ? 'active' : ''} onClick = {(e) => this.handleOnClick(e,i) }>{item.name}</a></li> )}
现在的点击功能看起来像-
handleOnClick = (event, index) => {
this.setState({activeItem: index});
}
所以您的组件看起来像
import React from 'react';
import NavItem from './NavItem';
export default class NavBar extends React.Component {
constructor() {
super();
this.menuItems = [
{
name: 'HOME',
url: '#'
}, {
name: 'NEWS',
url: '#'
}, {
name: 'CONTACT',
url: '#'
}
];
this.state = {
activeItem: 0
}
}
handleOnClick = (event, index) => {
this.setState({activeItem: index});
}
render() {
return (
<nav>
<ul>
CHOOSE: {this
.menuItems
.map((item, i) => <li>
<a
href={item.url}
className={this.state.activeItem == i
? 'active'
: ''}
onClick=
{(e) => this.handleOnClick(e,i) }>{item.name}</a>
</li>)}
</ul>
</nav>
);
}
}
我已经将默认设置为0的索引设置为活动状态,但是您可以根据需要进行更改。
答案 1 :(得分:0)
看起来像React Docs的文章Lifting State Up完全按照您演示的用例编写。
您正在隔离管理每个组件内的isActive
状态。 NavItem
的每个实例都不知道,也不应该知道NavItem
的其他实例的状态是什么
所以...提升您的状态!在Navbar
内部管理有关活动/非活动条的信息,并通过道具控制多个NavItem
实例。
它应该像这样:
NavBar.js
import React from 'react';
import NavItem from './NavItem';
export default class NavBar extends React.Component {
constructor() {
super();
this.state = {
menuItems: [
{ name: 'HOME', url: '#', isActive: true },
{ name: 'NEWS', url: '#', isActive: false },
{ name: 'CONTACT', url: '#', isActive: false }
]
};
this.menuItems = [];
}
onNavItemClick = itemName => {
const nextMenuItems = this.state.menuItems.map(item => {
if (item.name === itemName) {
return { ...item, isActive: true };
}
return { ...item, isActive: false };
});
this.setState({
menuItems: nextMenuItems
});
};
render() {
return (
<nav>
<ul>
CHOOSE:
{this.state.menuItems.map((item, i) => (
<NavItem
key={item.name}
name={item.name}
isActive={item.isActive}
onClick={this.onNavItemClick}
url={item.url}
/>
))}
</ul>
</nav>
);
}
}
NavItem.js
import React from 'react';
export default class NavItem extends React.Component {
constructor() {
super()
console.log()
this.onClickFunction = () => this.props.onClick(this.props.name);
}
render() {
let item = this.props.data;
return (
<li className={this.props.isActive ? 'active' : ''}>
<a
href={this.props.url}
onClick={this.onClickFunction}
>
{this.props.name}``
</a>
</li>
);
}
}
答案 2 :(得分:0)
也许您可以将<NavLink to="" activeStyle={{color: 'red'}} />
组件用作链接/标签(来自“ react-router-dom”)
答案 3 :(得分:0)
LiranC , Infinity ,感谢您的帮助和示例,我想我明白了。 我知道它会以将状态提升到NavBar结尾,只是不确定如何引用特定元素。
我希望当时只有一个元素处于活动状态,为了将来的目的使用列表项组件,因此我将其混合并提出了这样的代码。期待任何进一步的优化建议。
NavBar.js
import React from 'react';
import NavItem from './NavItem';
export default class NavBar extends React.Component {
constructor() {
super();
this.menuItems = [
{ name: 'HOME', url: '#' },
{ name: 'NEWS', url: '#' },
{ name: 'CONTACT', url: '#' }
];
this.state = {
activeItem: null
}
}
handleOnClick = (e,i) => {
this.setState({activeItem: i});
}
render() {
return (
<nav>
<ul>
CHOOSE:
{this.menuItems.map( (item,i) =>
<NavItem
key={i}
idn={i}
data={item}
isActive={this.state.activeItem == i ? true : false}
onClick={this.handleOnClick} />
)}
</ul>
</nav>
);
}
}
NavItem.js
import React from 'react';
export default class NavItem extends React.Component {
render() {
let item = this.props.data;
return (
<li>
<a
href={item.url}
className={this.props.isActive ? 'active' : ''}
onClick={ (e) => this.props.onClick(e, this.props.idn) }>{item.name}
</a>
</li>
);
}
}