人们! 我开始使用webpack,react,redux等构建应用程序。我不确定我是否应该面对我应该的情况:
我想开发一个单页应用程序,只有一个反应节点"< myApp />"这将包含内部的一切。我的页面上会出现的第一件事是引导导航栏。我想要的是创建一个反应组件,渲染导航栏并传递给他1)一个字符串列表,和2)一个函数,当点击其中一个项目时应该调用。我想以这种方式做到这一点,因为我想在顶层跟踪"页面"我在哪里(它将始终是导航栏项目之一)。
这是我的myApp组件:
export default class myApp extends React.Component {
constructor(props) {
super(props);
this.handleNavbarClick = ::this.handleNavbarClick;
this.state = {
currentPage: 'Home',
navbarItems : ['Home', 'contact', 'etc']
};
}
handleNavbarClick(e) {
//debug alert:
alert(e);
this.state.currentPage = e;
}
render() {
return (
<div>
<NavBar items={this.state.navbarItems} itemClickHandler={this.handleNavbarClick}/>
<Wellcome />
<LandingMenu />
CurrentPage: {this.state.currentPage}
</div>
);
}
}
这里是我的导航栏组件:
export default class NavBar extends React.Component {
constructor(props) {
super(props);
}
render() {
var handler = this.props.itemClickHandler;
var itemsHtml = this.props.items.map(function(i) {
return <li className="nav-item"> <a className="nav-link" onClick={handler(i)}>{i}</a></li>
});
return (
<nav className="navbar navbar-static-top navbar-dark bg-inverse">
<a className="navbar-brand" href="#"><img src={LogoSrhSmall} /></a>
<ul className="nav navbar-nav">
{itemsHtml}
</ul>
</nav>
)
}
}
实际上,当我点击其中一个导航栏项目时,没有任何反应,但是当页面加载时,会自动为每个项目调用函数handleNavbarClick的警报,我不明白为什么:(
有人可以告诉我,我做错了什么?我正确地面对问题?
提前致谢,
@ janaka-stevens,@赞,谢谢!
从您的答案中应用一些更改,我可以通过将其存储在属性&#34; id&#34;并访问它抛出e.target.id。 对于这种情况来说这很好,但是不要使用简单的字符串,我想使用一系列更复杂的对象,让我们说:
[
{ name: 'home', url: '/someroute', importantData: {...} },
{ name: 'otherLink', url: '/someOtherroute' , importantData: {...} }
]
我想将完整的选定对象传递给父myApp?
目前,它看起来像是:
on myApp:
...
handleNavbarClick(e) {
this.setState({currentPage : e.target.id}) ;
}
...
并在NavBar上:
...
renderNavItem(item) {
return (<li className="nav-item">
<a id={item} className="nav-link" onClick={this.props.itemClickHandler}>{item}</a>
</li>)
}
render() {
return (
<nav className="navbar navbar-static-top navbar-dark bg-inverse">
<a className="navbar-brand" href="#"><img src={LogoSrhSmall} /></a>
<ul className="nav navbar-nav">
{this.props.items.map(this.renderNavItem, this)}
</ul>
</nav>
)
}
...
但是如果在&lt; a&gt;标记,而不是使用:
onClick={this.props.itemClickHandler}
我用:
onClick={this.props.itemClickHandler(item)}
每次渲染迭代都会调用itemClickHandler,因为反应将会调用&#34;迭代项目以显示它们的方法(没有任何用户交互)....任何想法为什么?
提前致谢, 约翰
答案 0 :(得分:1)
你有两个问题。第一个是handleNavbarClick(e)中的e是事件。您想要做的是为每个项目列表提供一个标识符。然后你会得到e.target.id。当然,您还需要在映射列表中添加id。第二个问题是你需要通过这个&#39;你的映射列表就像这样;
render() {
var itemsHtml = this.props.items.map(function(i) {
return <li className="nav-item"> <a id={i.id} className="nav-link" onClick={this.props.itemClickHandler}>{i}</a></li>
}, this);
&#13;
注意地图中的第二个参数。
答案 1 :(得分:1)
我将建议您对代码进行一些更改,以使其更易于阅读:
对于itemClickHandler
,您使用(e)
以外的内容,因为e
通常表示事件。为此,你应该itemClickHandler(page)
。
然后在Navbar组件中,你可能想要做这样的事情:
export default class NavBar extends React.Component {
constructor(props) {
super(props);
}
renderNavItem(item) {
<li className="nav-item">
<a className="nav-link" onClick={this.props.handleNavbarClick(item)}>{item}</a>
</li>
}
render() {
return (
<nav className="navbar navbar-static-top navbar-dark bg-inverse">
<a className="navbar-brand" href="#"><img src={LogoSrhSmall} /></a>
<ul className="nav navbar-nav">
{this.props.items.map(this.renderNavItem)}
</ul>
</nav>
)
}
}
但你做错的主要事情是你永远不会设置状态。
React中的#1规则是你永远不想改变道具或状态(通过做this.prop.whatever = blar
或this.state.whatever = blar
。如果你这样做,那么什么都不会改变,你可以改变组件。重新传递道具或状态可能没有正确的信息。所以如果你想改变状态,你必须拨打this.setState({currentPage: page})
。
因此,在handleNavbarClick
内,您要将其更改为:
handleNavbarClick(page) {
//debug alert:
alert(page);
this.setState({currentPage: page});
}
这将告诉React你已经改变了状态并希望重新渲染。
答案 2 :(得分:0)
我遇到的问题是处理程序自己运行而没有实际单击按钮。我用一个像你是第一个的参数调用处理程序。我删除了,行为停止了。我尝试了bind(null,props)技巧,它适用于道具,但我不知道如何在处理程序中访问事件本身,所以我可以e.preventDefault()。
在找了一分钟后,我找到了这个gem,它遍历函数收到的所有未命名参数。
for (var i=0; i<arguments.length; i++) {
console.log(arguments[i])
};
使用它,我可以使用
访问处理程序中的事件e = arguments[1]
现在一切都很顺利。
感谢您给我一个起点!