Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React-更新状态以从选项卡导航添加/删除活动类_Javascript_Reactjs - Fatal编程技术网

Javascript React-更新状态以从选项卡导航添加/删除活动类

Javascript React-更新状态以从选项卡导航添加/删除活动类,javascript,reactjs,Javascript,Reactjs,我在页面顶部有一个选项卡导航,我想在单击该选项卡时向该选项卡添加一个“活动”类,并确保它不在任何其他选项卡上 到目前为止,我已经将“active”类添加到了第一个选项卡中,但是如果单击任何其他选项卡,则不会更新。因此,无论单击什么,第一个选项卡始终是活动选项卡 import React from 'react' import { string } from 'prop-types' class TabNav extends React.Component { constructor(pro

我在页面顶部有一个选项卡导航,我想在单击该选项卡时向该选项卡添加一个“活动”类,并确保它不在任何其他选项卡上

到目前为止,我已经将“active”类添加到了第一个选项卡中,但是如果单击任何其他选项卡,则不会更新。因此,无论单击什么,第一个选项卡始终是活动选项卡

import React from 'react'
import { string } from 'prop-types'

class TabNav extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      currentTab: ''
    }

    this.handleClick = this.handleClick.bind(this)
    this.createTabItems = this.createTabItems.bind(this)
  }

  shouldComponentUpdate (nextProps, nextState) {
    return nextProps.navItems !== this.props.navItems
  }

  handleClick (currentTab) {
    this.setState({
      currentTab: currentTab
    })
    this.createTabItems()
  }

  createTabItems () {
    const { navItems = false } = this.props
    if (!navItems) return false
    const splitItems = navItems.split(',')
    if (!splitItems.length) return false
    return splitItems.map((item, currentTab) => {
      const items = item.split('_')
      if (items.length !== 3) return null
      const itemLink = items[1]
      return (
        <li key={currentTab} className={this.state.currentTab == currentTab ? 'side-nav-tab active' : 'side-nav-tab'} onClick={this.handleClick.bind(this, currentTab)}>
            <a href={itemLink}>
              <p>{ items[0] }</p>
            </a>
        </li>
      )
    })
  }

  render () {
    const tabItems = this.createTabItems()
    if (!tabItems) return null
    return (
      <div>
        <ul id='tabNavigation'>
          {tabItems}
        </ul>
      </div>
    )
  }
}

TabNav.propTypes = {
  navItems: string.isRequired
}

export default TabNav

我认为是您的
shouldComponentUpdate
导致了这个问题。你能试着把它取下来吗?另外,您不需要在
handleClick()

中调用
this.createTabItems
,我觉得这里需要一个思维方式的转变,以便更具声明性地思考,您不需要告诉React何时要创建选项卡,它将通过呈现方法和传递给它的数据来确定这一点

我已经删除了你的componentShouldUpdate函数,因为React已经为你比较了这些道具。我还通过索引跟踪所选项目,因为它简化了我头脑中的逻辑

试着这样做:

import React from 'react';
import { string } from 'prop-types';

class TabNav extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      selectedIndex: 0
    };
  }

  handleClick = index => {
    this.setState({
      selectedIndex: index
    });
  };

  render() {
    const { navItems = [] } = this.props;

    return (
      <div>
        <ul id="tabNavigation">
          {navItems.map((navItem, index) => {
            if (navItem.length !== 3) return;

            const [text, link] = navItem;

            return (
              <li
                className={
                  this.state.selectedIndex === index
                    ? 'side-nav-tab active'
                    : 'side-nav-tab'
                }
                onClick={this.handleClick.bind(null, index)}
              >
                <a href={link}>
                  <p>{text}</p>
                </a>
              </li>
            );
          })}
          }
        </ul>
      </div>
    );
  }
}

TabNav.propTypes = {
  navItems: string.isRequired
};

export default TabNav;
从“React”导入React;
从“属性类型”导入{string};
类TabNav扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
已选择索引:0
};
}
handleClick=索引=>{
这是我的国家({
selectedIndex:索引
});
};
render(){
const{navItems=[]}=this.props;
返回(
    {navItems.map((navItem,index)=>{ 如果(navItem.length!==3)返回; const[text,link]=navItem; 返回(
  • ); })} }
); } } TabNav.propTypes={ navItems:string.isRequired }; 导出默认TabNav;
这里还有一些其他的变化,比如从数组中解构而不是使用索引,这样可以更清楚地了解从navItem数组中提取的属性是什么


我还在handleClick函数中使用了一个胖箭头函数,因为这意味着你不必在构造函数中绑定到
this

你遇到了两个问题,第一个是你在函数中使用
this
的方式,第二个是你的
应该更新组件,就像我前面提到的那个一样。如果要使用
引用类,则需要使用箭头函数。请记住,ES6 arrow函数使用词法范围,这意味着
引用包含函数的代码。我用一个工作示例对下面的代码进行了更改

类TabNav扩展了React.Component{ 建造师(道具){ 超级(道具) 此.state={ 当前选项卡:“” } this.handleClick=this.handleClick.bind(this) this.createTabItems=this.createTabItems.bind(this) } handleClick(当前选项卡){ 这是我的国家({ 当前选项卡:当前选项卡 }) } createTabItems=()=>{ const{navItems=false}=this.props 如果(!navItems)返回false 常量splitItems=navItems.split(',') 如果(!splitItems.length)返回false 返回splitItems.map((项目,当前选项卡)=>{ 常量项=项拆分(“”) 如果(items.length!==3)返回null const itemLink=项目[1] 返回(
  • ) }) } 渲染(){ const tabItems=this.createTabItems() 如果(!tabItems)返回null 返回(
      {tabItems}
    ) } } 类Nav扩展了React.Component{ render(){ 返回( ) } } ReactDOM.render(,document.getElementById('root'))
    .active{
    字体大小:20px;
    }
    
    
    不相关,但是
    createTabItems
    中的一些空白将大大有助于提高可读性。严格来说,这不是真的,您不必使用胖箭头函数来使用
    这个
    ,这只是一个省时的方法。如果您不想使用胖箭头函数,构造函数中的绑定会处理这个问题。
    
    import React from 'react';
    import { string } from 'prop-types';
    
    class TabNav extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          selectedIndex: 0
        };
      }
    
      handleClick = index => {
        this.setState({
          selectedIndex: index
        });
      };
    
      render() {
        const { navItems = [] } = this.props;
    
        return (
          <div>
            <ul id="tabNavigation">
              {navItems.map((navItem, index) => {
                if (navItem.length !== 3) return;
    
                const [text, link] = navItem;
    
                return (
                  <li
                    className={
                      this.state.selectedIndex === index
                        ? 'side-nav-tab active'
                        : 'side-nav-tab'
                    }
                    onClick={this.handleClick.bind(null, index)}
                  >
                    <a href={link}>
                      <p>{text}</p>
                    </a>
                  </li>
                );
              })}
              }
            </ul>
          </div>
        );
      }
    }
    
    TabNav.propTypes = {
      navItems: string.isRequired
    };
    
    export default TabNav;