React组件问题:点击导航菜单项无法新增<li>,仅更新原有内容
解决React中点击菜单项无法新增Tab标签页的问题
我仔细看了你的代码,发现问题出在openTabs方法的状态更新逻辑上——你没有遵循React状态不可变性的原则,而且状态更新的写法也有问题,导致每次点击菜单都只是更新了现有tab的内容,而没有新增新的tab。咱们一步步来修复它:
1. 修复openTabs方法的状态更新逻辑
你原来的代码直接修改了原状态数组(state.tabs.tabsLi.push(...)),而且错误地把整个state对象嵌套进去设置新状态,这会让React无法正确检测到数组的变化。正确的做法是创建新数组,保持状态不可变:
openTabs(e, url, iframe, trdtitle){ e.preventDefault(); // 用扩展运算符创建新数组,添加新的tab标题 const updatedTabsLi = [...this.state.tabs.tabsLi, trdtitle]; // 只更新需要改变的状态部分,保留其他属性 this.setState({ tabs: { ...this.state.tabs, tabsLi: updatedTabsLi }, showtabs: false }); }
另外,你之前用trdtitle.split()会把字符串拆成单个字符的数组,这显然不是你想要的,直接用trdtitle本身就可以了。
2. 修复Tab关闭按钮的点击逻辑
你当前的onClick={remove_tab(index)}会在组件渲染时就执行关闭方法,而不是点击按钮时执行。需要改成箭头函数来传递参数,同时还要在父组件实现关闭tab的方法:
第一步:在父组件App中添加removeTab方法
先在constructor里绑定这个方法:
constructor(props, context){ super(props, context); // 把removeTab也加入绑定列表 ["openTabs", "removeTab"].forEach((method) => { this[method] = this[method].bind(this); }); this.state = { navigation: { menu: [], }, tabs:{ tabsLi:[], }, showtabs: true, } }
然后实现removeTab方法:
removeTab(index){ // 过滤掉要删除的tab,创建新数组 const updatedTabsLi = this.state.tabs.tabsLi.filter((_, tabIndex) => tabIndex !== index); this.setState({ tabs: { ...this.state.tabs, tabsLi: updatedTabsLi }, // 如果没有tab了,恢复初始提示状态 showtabs: updatedTabsLi.length === 0 }); }
第二步:在Tabs组件中修改关闭按钮的点击事件
同时要确保Tabs组件能拿到父组件传递的removeTab方法:
// 在Tabs组件的render方法里修改Icon的onClick <Icon icon="cerrar" className='ico-cerrar' onClick={() => this.props.removeTab(index)}/>
然后在父组件渲染Tabs时传递这个方法:
<Tabs tabs={this.state.tabs} showtabs={this.state.showtabs} removeTab={this.removeTab}/>
3. 清理多余状态
你原来的textvalue状态看起来是多余的,因为我们直接把tab标题添加到tabsLi数组里了,可以从state中删掉它。
修改后的完整代码片段
App组件
class App extends Component { constructor(props, context){ super(props, context); ["openTabs", "removeTab"].forEach((method) => { this[method] = this[method].bind(this); }); this.state = { navigation: { menu: [], }, tabs:{ tabsLi:[], }, showtabs: true, } } componentDidMount() { fetch('json_menu.php') .then(response => response.json()) .then(data =>{ this.setState({navigation: data}); }) } openTabs(e, url, iframe, trdtitle){ e.preventDefault(); const updatedTabsLi = [...this.state.tabs.tabsLi, trdtitle]; this.setState({ tabs: { ...this.state.tabs, tabsLi: updatedTabsLi }, showtabs: false }); } removeTab(index){ const updatedTabsLi = this.state.tabs.tabsLi.filter((_, tabIndex) => tabIndex !== index); this.setState({ tabs: { ...this.state.tabs, tabsLi: updatedTabsLi }, showtabs: updatedTabsLi.length === 0 }); } render() { // 这里假设你会渲染导航菜单,调用openTabs方法 return ( <div> {/* 导航菜单渲染部分 */} <Tabs tabs={this.state.tabs} showtabs={this.state.showtabs} removeTab={this.removeTab}/> </div> ) } }
Tabs组件
class Tabs extends Component { render(){ const renderTabs = () => { return( <div id="content-tabs" className="tabs"> {this.props.showtabs ? ( <div className="waiting-leads"> <p>Parece que todavía no hay ningún lead...</p> <h3>¡Ánimo, ya llega!</h3> <img src={imgDinosaurio} alt="Dinosaurio"></img> </div> ) : ( <ul id="resizable" className="content" > {this.props.tabs.tabsLi.map((value, index) => { return ( <li key={index}> <span>{value}</span> <Icon icon="cerrar" className='ico-cerrar' onClick={() => this.props.removeTab(index)}/> </li> ) })} </ul> )} </div> ); } return ( <> {renderTabs()} </> ) } }
这样修改后,每次点击菜单项都会新增一个独立的tab,而不是更新现有tab,而且关闭按钮也能正常工作啦。
内容的提问来源于stack exchange,提问作者Casandra
相关产品推荐
相关产品推荐

