arrays - Set initial active element, after resizing array of elements
问题描述
I'm kind a stuck on this. There is this standard tab menubar which receives it's data externally(array). Initial state has full array, but during work, this array gets filtered. After filter, active class should mark first element whom receives data from newly filtered array. But my logic, for some reason, marks element with index 1(letters: one) instead of zero(letters: zero) as active. Filtering is good, no objection on that part. Trouble is that this is done in React, so there are some guidelines that needs to be followed here.
Function that sets element active on click:
setActive(e){
e.preventDefault();
let elem = e.target;
let len1 = elem.attributes.length;
let obj1 = {};
let name = null;
let value = null;
for(let i=0;i<len1;i++){
let attr = elem.attributes[i];
name = attr.name;
value = attr.value;
obj1[name] = value;
}
//Begin: Important for question asked.
let allTabs = document.querySelectorAll(".nav-link");
let len2 = allTabs.length;
for(let i=0;i<len2;i++){
if(allTabs[i]===elem){
this.setState({
elemIndex: i
});
}
}
//End: Important for question asked.
this.setState(obj1);
}
Logic that filters out elements and resets active class, it's in render method:
let elemIndex = this.state.elemIndex;
let active = null;
let menu = this.state.menu.filter((item, i) => {
if(this.state.access_token===null && item==="register"){
return item;
}
if(this.state.access_token===null && item==="login"){
return item;
}
if(this.state.access_token!==null && item==="create"){
return item;
}
if(this.state.access_token!==null && item==="show"){
return item;
}
if(this.state.access_token!==null && item==="update"){
return item;
}
if(this.state.access_token!==null && item==="delete"){
return item;
}
if(this.state.access_token!==null && item==="list"){
return item;
}
});
let lis = menu.map((item, i) => {
console.log((elemIndex===i || (i===0 && elemIndex===0)), elemIndex, i);
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <li className="nav-item" key={i} id={i}>
<a className={"nav-link" + active} data-toggle="tab" href={"menu"+(i+1)} onClick={this.setActive}>
{item}
</a>
</li>;
});
let tabContents = menu.map((item, i) => {
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <div id={"menu"+(i+1)} key={i} className={"container tab-pane" + active}><br/>
{item==="register" ? <Register register={this.register}/> : null}
{item==="login" ? <Login login={this.login}/> : null}
{this.state.access_token!==null && item==="create" ? <CreatePost createPost={this.createPost}/> : null}
{this.state.access_token!==null && item==="show" && this.state.posts!==null ? <ShowPost onChange={this.onChange} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="list" && this.state.posts!==null ? <ListPosts posts={this.state.posts}/> : null}
{this.state.access_token!==null && item==="update" && this.state.posts!==null ? <UpdatePost onChange={this.onChange} updatePost={this.updatePost} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="delete" && this.state.posts!==null ? <DeletePost onChange={this.onChange} updatePost={this.deletePost} posts={this.state.posts} post={this.state.post}/> : null}
</div>;
});
Other methods called are of no concern since they don't have anything to do with setting active class.
解决方案
弄清楚了。
首先,我将过滤设置为一个单独的函数和单独的属性以包含过滤后的数组,其次我设置活动元素的逻辑很好,所以那里没有变化。第三,我进行了评估,以便当过滤后的数组不为空时,用于映射所有标签栏元素。
过滤方法:
filterize(){
let menu = this.state.menu.filter((item, i) => {
let access_token = this.state.access_token;
if(access_token===null && item==="register"){
return item;
}
if(access_token===null && item==="login"){
return item;
}
if(access_token!==null && item==="create"){
return item;
}
if(access_token!==null && item==="show"){
return item;
}
if(access_token!==null && item==="update"){
return item;
}
if(access_token!==null && item==="delete"){
return item;
}
if(access_token!==null && item==="list"){
return item;
}
});
this.setState({
filteredMenu: [...menu],
elemIndex: 0
});
}
componentDidMount(){//This needs to be since extracted logic isn't in render anymore.
this.filterize();
}
在渲染方法中:
let elemIndex = this.state.elemIndex;
let active = null;
let lis = this.state.filteredMenu ? this.state.filteredMenu.map((item, i) => {
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <li className="nav-item" key={i} id={i}>
<a className={"nav-link" + active} data-toggle="tab" href={"menu"+(i+1)} onClick={this.setActive}>
{item}
</a>
</li>;
}) : this.state.menu.map((item, i) => {
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <li className="nav-item" key={i} id={i}>
<a className={"nav-link" + active} data-toggle="tab" href={"menu"+(i+1)} onClick={this.setActive}>
{item}
</a>
</li>;
});
let tabContents = this.state.filteredMenu ? this.state.filteredMenu.map((item, i) => {
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <div id={"menu"+(i+1)} key={i} className={"container tab-pane" + active}><br/>
{item==="register" ? <Register register={this.register}/> : null}
{item==="login" ? <Login login={this.login}/> : null}
{this.state.access_token!==null && item==="create" ? <CreatePost createPost={this.createPost}/> : null}
{this.state.access_token!==null && item==="show" && this.state.posts!==null ? <ShowPost onChange={this.onChange} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="list" && this.state.posts!==null ? <ListPosts posts={this.state.posts}/> : null}
{this.state.access_token!==null && item==="update" && this.state.posts!==null ? <UpdatePost onChange={this.onChange} updatePost={this.updatePost} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="delete" && this.state.posts!==null ? <DeletePost onChange={this.onChange} updatePost={this.deletePost} posts={this.state.posts} post={this.state.post}/> : null}
</div>;
}) : this.state.menu.map((item, i) => {
active = elemIndex===i || (i===0 && elemIndex===0) ? " active" : "";
return <div id={"menu"+(i+1)} key={i} className={"container tab-pane" + active}><br/>
{item==="register" ? <Register register={this.register}/> : null}
{item==="login" ? <Login login={this.login}/> : null}
{this.state.access_token!==null && item==="create" ? <CreatePost createPost={this.createPost}/> : null}
{this.state.access_token!==null && item==="show" && this.state.posts!==null ? <ShowPost onChange={this.onChange} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="list" && this.state.posts!==null ? <ListPosts posts={this.state.posts}/> : null}
{this.state.access_token!==null && item==="update" && this.state.posts!==null ? <UpdatePost onChange={this.onChange} updatePost={this.updatePost} posts={this.state.posts} post={this.state.post}/> : null}
{this.state.access_token!==null && item==="delete" && this.state.posts!==null ? <DeletePost onChange={this.onChange} updatePost={this.deletePost} posts={this.state.posts} post={this.state.post}/> : null}
</div>;
});
不确定这些东西是否有更短的代码,但至少它尊重指南。
推荐阅读
- ajax - 关于 Framework7-vue-cli Ajax 拦截器
- jsoup - Jsoup 不读取/加载整个页面
- leaflet - 传单地图上下文菜单位置
- amazon-web-services - 如何使用 AWS CLI 确定 AWS 资源属于哪个 CloudFormation 堆栈?
- java - 实例缓存清理
- count - 在 SPARQL 中使用 LIMIT 时如何获取结果总数?
- java - 在我的 Square 类中创建绘画图形 g 破坏了我的 GUI
- java - 如何在 oracle 中查看启用休眠的 java 程序执行的最近 sql 命令的事务日志(带有时间和性能信息)
- javascript - 如何为表格设置垂直和水平滚动条?
- python - Python Selenium Instagram 机器人