我正在学习反应,并想要实现一个基本的导航栏,其中包含一些项目,我想让我点击的最后一个让className处于活动状态,而其他所有项目都没有。
在下面的代码中,我无法使用item.setState删除resetALL中的className(是的,通过阅读我理解它不起作用的文档),所以我尝试使用jQuery直接操作dom。它适用于第一次单击,但第二次单击无效。是否有任何反应本地方式来做到这一点?谢谢。
$(document).ready(function(){
var NavItem = React.createClass({
getInitialState: function() {
return this.props.item;
},
handleClick: function() {
React.render(<span>{this.props.item.description}</span>, document.getElementById('main'));
this.props.resetALL();
console.log("this", this);
this.setState({active: true});
},
render: function() {
var className = this.state.active ? "active" : "";
return <li className={className}><a href="#" onClick={this.handleClick}>{this.props.item.description}</a></li>;
}
});
var NavBar = React.createClass({
items : [],
resetALL: function() {
this.items.forEach(function(item) {
console.log("item", item);
// item.setState({active: false});
});
$("#nav-sidebar li").each(function(){
$(this).removeClass("active");
});
},
render: function() {
var _this = this;
this.props.items.forEach(function(item) {
console.log("handleClick", this.handleClick);
_this.items.push(<NavItem item={item} key={item.id} resetALL={_this.resetALL}/>);
});
return (
<ul className="nav nav-sidebar" id="nav-sidebar">
{this.items}
</ul>
);
}
});
var NAVLIST = [
{id: 1, description: 'OverView', active: true},
{id: 2, description: 'Calls'},
{id: 3, description: 'Channels'},
{id: 4, description: 'OverView'}
]
React.render(<NavBar items = {NAVLIST} />, document.getElementById('sidebar'));
React.render(
<h1>Hello, FreeSWITCH!</h1>,
document.getElementById('main')
);
});
答案 0 :(得分:0)
当environments {
'headless-ff' {
driver = {
pdriver = new PhantomJSDriver(new DesiredCapabilities())
pdriver.manage().window().maximize()
pdriver
}
}
}
调用NavItem
时,该函数不会绑定到this.props.resetALL()
,因此它无法遍历NavBar
&#39}。的项目。您可以将它绑定到正确的范围,如下所示:
NavBar
答案 1 :(得分:0)
好吧,我看到你的代码中的一些东西在反应中有点不常见:
set "var=abc"
set "var=123" & cmd /v /c"echo !var!"
元素有点会破坏react.js的目的。相反,您应该通过属性和事件进行沟通,并让main
更新您想要的文字react
main
不应负责设置其活动状态,NavItem
是一个更合适的地方,因为它包含其他项目,并且可以轻松激活/停用所需的项目NavBar
数组保存到items
而不是成员变量,因为只要您想激活其他项目,只需更新状态state
中的反应组件只是反应方式,您不需要直接存储和访问组件_this.items.push
您可以在下面找到react.js解决问题的自然方法。这里要注意三件事:
1.数据下降,事件上升
2. $(document).ready()
用于让反应知道某些事情发生了变化
3.有一个汇总setState
组件可帮助您更新文本
App
答案 2 :(得分:0)
你是否对使用jQuery更新由React管理的DOM元素的类表示怀疑是正确的。每当React重新渲染时,您的jQuery更改通常会被覆盖。要好好使用React,你必须经常思考和重新思考你试图用你的应用程序表示的内容,以及定义其状态的数据应该自然存在的地方。
在此示例中,您尝试渲染导航链接列表,其中只有一个处于活动状态。 NavBar是一个更合理的存储项,它比NavItem的状态更活跃。
我建议将项目列表作为道具传递给NavList,并将最初活动的项目存储在NavList的状态中,或者将其作为清楚标记的initialActiveItem传递,如下所示:
<NavList items={NAVLIST} initialActiveItem={1} />
但是活动项的id应该存储在NavList的状态中,而不是props,所以这样做的一种方法是使用NavList的getInitialState生命周期方法来初始化活动项:
getInitialState: function() { return { activeItem: this.props.initialActiveItem }; },
当您需要更新活动项目时,例如在单击处理程序中,您可以使用setState调用,例如this.setState({activeItem: 2}
我在NavList上定义一个函数,它接受一个id并调用它的setState方法将活动项设置为该id,然后将该函数作为prop传递给每个项(在这一行中this
是NavBar实例,item
是this.props.items
)的一个元素:
<NavItem id={item.id} update={this.updateActive} key={item.id} active={this.state.activeId == item.id} />
NavItem只需要知道它的props.active是否为true以决定是否呈现活动className,以及如何将其id返回到NavBar的updateActive函数以使其自身处于活动状态(如果尚未激活) 。当NavBar更新时,它将重新渲染其子NavItems,并且它们将使用正确的活动状态进行更新,以便它们可以自己呈现正确的classNames。
当然,如果单击NavItems的目的不仅仅是更新该项是否处于活动状态,您还必须确保该单击会触发任何其他相关操作。如果这意味着更新完全不同的React组件的内容,比如您在#main中呈现的内容,请考虑您将存储和检索有关该其他组件中应包含内容的状态信息的位置。它可能应该是这两个元素的父级,或者是一些其他共享的有状态资源,如Flux Store。有关如何推断此信息所在位置的更多信息,请参阅https://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html。