aer*_*ugo 8 javascript menu onclick reactjs
我对React和Javascript都很陌生,我已经开始通过构建一个简单的可折叠菜单来学习它.它按预期工作,除了我无法弄清楚如何一次只突出显示一个项目.我怀疑onClick方法和状态必须由比sectionItem更高级别的类所拥有,但我真的陷入了如何使这项工作.我的第一直觉就是每次点击某些内容时迭代菜单中的所有项目,并确保所有其他项目都切换为active = false.
这是考虑这个问题的正确方法吗?在这种情况下,有人可以解释一下状态如何在React中运行,以及我应该如何在这里实现它?
整个代码可在此处获得:codepen.io上的菜单
这是我想要突出显示的项目的代码.我还没有能够实现一次只突出显示一个项目.
var SectionItem = React.createClass({
handleClick: function(){
if(!this.state.active) {
this.setState({
currentItem: this,
active: true,
class: "sectionitem active"});
}
},
getInitialState: function(){
return {
active: false,
class: "sectionitem"
}
},
render: function() {
return (
<div className={this.state.class} onClick={this.handleClick}>{this.props.title}</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
fir*_*oit 10
好开始!让我们先在代码中解决一些问题.
无需在最顶层组件中创建整个嵌套结构.这是非常人为的:
for (i=0; i < this.props.menuitems.length; i++) {
if(this.props.menuitems[i].section !== lastSection) {
var section = this.props.menuitems[i].section;
var items = [];
for (j=0; j < this.props.menuitems.length; j++) {
if(this.props.menuitems[j].section == section) {
var itemName = this.props.menuitems[j].name;
items.push(<SectionItem title={itemName} key={itemName} />);
};
}
sections.push(<Section title={section} items={items} key={section} />);
lastSection = section;
}
}
Run Code Online (Sandbox Code Playgroud)
恰恰相反.您应该尝试让每个组件负责呈现他们自己的信息.如果我们首先处理您的数据,我们可以改进这一点 问题是您的部分不是嵌套的.如果,而不是......
var MENU_ITEMS = [
{section: "About", name: "Hey", key: "Hey", selected: true},
{section: "About", name: "No", key: "No", selected: false},
{section: "About", name: "Way", key: "Way", selected: false},
{section: "People", name: "Cakewalk", key: "Cakewalk", selected: false},
{section: "People", name: "George", key: "George", selected: false},
{section: "People", name: "Adam", key: "Adam", selected: false},
{section: "Projects", name: "Pirate raid", key: "Pirate raid", selected: false},
{section: "Projects", name: "Goosehunt", key: "Goosehunt", selected: false},
];
Run Code Online (Sandbox Code Playgroud)
我们有这个:
var sections = [
{
name: "About",
items: [
{name: "Hey", key: "Hey", selected: true},
{name: "No", key: "No", selected: false},
{name: "Way", key: "Way", selected: false}
]
},{
name: "People",
items: [
{name: "Cakewalk", key: "Cakewalk", selected: false},
{name: "George", key: "George", selected: false},
{name: "Adam", key: "Adam", selected: false}
]
},{
name: "Projects",
items: [
{name: "Pirate raid", key: "Pirate raid", selected: false},
{name: "Goosehunt", key: "Goosehunt", selected: false}
]
}
];
Run Code Online (Sandbox Code Playgroud)
然后我们可以简化Accordion很多.我们只Section为每个渲染一个section:
var Accordion = React.createClass({
render: function() {
return (
<div className="main">
{this.props.sections.map(function(section){
return <Section key={section.name} section={section}/>
})}
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
同样,Section和SectionItem变得相当简单.
var Section = React.createClass({
handleClick: function(){
this.setState({
open: !this.state.open,
class: this.state.open ? "section" : "section open"
});
},
getInitialState: function(){
return {
open: false,
class: "section"
}
},
render: function() {
return (
<div className={this.state.class}>
<div className="sectionhead" onClick={this.handleClick}>{this.props.section.name}</div>
<div className="articlewrap">
<div className="article">
{this.props.section.items.map(function(item){
return <SectionItem key={item.name} item={item}/>
})}
</div>
</div>
</div>
);
}
});
var SectionItem = React.createClass({
handleClick: function(){
this.setState({
currentItem: this,
active: !this.state.active,
class: this.state.active ? "sectionitem" : "sectionitem active"
});
},
getInitialState: function(){
return {
active: false,
class: "sectionitem"
}
},
render: function() {
return (
<div className={this.state.class} onClick={this.handleClick}>{this.props.item.name}</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
现在,问你原来的问题.在更复杂的应用程序中,您可以从像Flux这样更强大的东西中受益.但是,就目前而言,遵循Thinking in React中暴露的技术应该可以解决您的问题.
实际上,一个好的方法是将你的"开放的"状态带入Accordion组件.您只需要让您的父母知道正在点击某些内容.我们可以通过作为a传递的回调来做到这一点prop.
所以,Accordion可以有一个openSection州,一个onChildClick收到被点击的部分的名字.它需要传递onChildClick给每个人Section.
var Accordion = React.createClass({
getInitialState: function() {
return {
openSection: null
};
},
onChildClick: function(sectionName) {
this.setState({
openSection: sectionName
});
},
render: function() {
return (
<div className="main">
{this.props.sections.map(function(section){
return <Section key={section.name}
onChildClick={this.onChildClick}
open={this.state.openSection===section.name}
section={section}/>
}.bind(this))}
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
并且Section点击时只需调用这个函数,传递它自己的名字.
var Section = React.createClass({
handleClick: function(){
this.props.onChildClick(this.props.section.name);
},
render: function() {
var className = this.props.open ? "section open" : "section"
return (
<div className={className}>
<div className="sectionhead" onClick={this.handleClick}>{this.props.section.name}</div>
<div className="articlewrap">
<div className="article">
{this.props.section.items.map(function(item){
return <SectionItem key={item.name} item={item}/>
})}
</div>
</div>
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
您可以根据SectionItem问题推断此解决方案.
最终的codepen在这里:http://codepen.io/gadr90/pen/wamQXG?edit = 001
学习React祝你好运!你是在正确的道路上.
| 归档时间: |
|
| 查看次数: |
2218 次 |
| 最近记录: |