在选定的选项卡上激活添加类激活

时间:2016-07-18 12:09:36

标签: reactjs

我有以下内容:

var Tab = React.createClass({
    getInitialState: function(){
        return {
          selected:''
        }
    },
    activateTab: function(e) {
        e.preventDefault();
        $('.navigation--active').removeClass('navigation--active');
        this.setState({selected  : true});
    },
    render: function() {
        var isActive = this.state.selected === true ? 'navigation--active': '';
        return (
            <li onClick={this.activateTab} className={isActive}>
                <p>
                    {this.props.content}
                </p>
            </li>
        );
    }
});

var Tabs = React.createClass({
    render: function() {
        var tabs = [],
            total = this.props.data.points.total,
            handleClick = this.handleClick;
        total.forEach(function(el, i){
            tabs.push(
                <Tab content = {el.name} 
                     key = {i}/>
            );
        });
        return (
            <ul className="navigation">
                {tabs}
            </ul>
        );
    }
});

然而,只有当你在每个标签上点击一次时它才有效,如果你在同一个标​​签上第二次点击该课程就不再添加了

2 个答案:

答案 0 :(得分:16)

在这种情况下,最好将状态管理移动到父组件Tabs,并将仅需要检测类名称或在父项中设置新状态的子项传递给子项

var Tab = React.createClass({
  render: function() {
    return <li 
      className={ this.props.isActive ? 'navigation--active': '' }
      onClick={ this.props.onActiveTab }
    >
      <p>{ this.props.content }</p>
    </li>
  }
});

var Tabs = React.createClass({
  getInitialState: function() {
    return { selectedTabId: 1 }
  },
  
  isActive: function (id) {
    return this.state.selectedTabId === id;
  },
  
  setActiveTab: function (selectedTabId) {
    this.setState({ selectedTabId });
  },
  
  render: function() {
    var total = this.props.data.points.total,
    	tabs = total.map(function (el, i) {
          return <Tab 
            key={ i }
            content={ el.name } 
            isActive={ this.isActive(el.id) } 
            onActiveTab={ this.setActiveTab.bind(this, el.id) }
          />
        }, this);
                
    return <ul className="navigation">
     { tabs }
    </ul>
  }
});

const data = {
  points: {
    total: [
      { id: 1, name: 'tab-1', text: 'text' },
      { id: 2, name: 'tab-2', text: 'text-2' },
      { id: 3, name: 'tab-3', text: 'text-2' }
    ]
  }
}

ReactDOM.render(
  <Tabs data={ data } />,
  document.getElementById('container')
);
.navigation {}

.navigation--active {
  color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>

答案 1 :(得分:0)

Necro海报在这里。 上面的答案很酷!

无论如何,这是带有recomposestyled-components的2018年升级答案。您甚至可以使用它来创建HOC,以获得令人愉快的可重用性!

https://codesandbox.io/s/1826454zl7

import React from "react";
import ReactDOM from "react-dom";
import { compose, withState, withHandlers } from "recompose";
import styled from "styled-components";

const enchancer = compose(
  withState("selectedTabId", "setSelectedTabId", 1),
  withHandlers({
    isActive: props => id => {
      return props.selectedTabId === id;
    },
    setActiveTab: props => id => {
      props.setSelectedTabId(id);
    }
  })
);

const Tabs = enchancer(props => {
  return (
    <ul>
      {props.data.map((el, i) => {
        return (
          <Tab
            key={i}
            content={el.name}
            isActive={props.isActive(el.id)}
            onActiveTab={() => props.setActiveTab(el.id)}
          />
        );
      })}
    </ul>
  );
});

const Tab = props => {
  return (
    <StyledLi isActive={props.isActive} onClick={props.onActiveTab}>
      <p>{props.content}</p>
    </StyledLi>
  );
};

const StyledLi = styled.li`
  font-weight: ${({ isActive }) => (isActive ? 600 : 100)};
  cursor: pointer;
  font-family: Helvetica;
  transition: 200ms all linear;
`;

const data = [
  { id: 1, name: "tab-1", text: "text" },
  { id: 2, name: "tab-2", text: "text-2" },
  { id: 3, name: "tab-3", text: "text-2" }
];

const ExampleApp = () => <Tabs data={data} />;

ReactDOM.render(<ExampleApp />, document.getElementById("app"));

基本思想是,您需要获取选定的索引,在每次单击时映射该项目,将选定的索引与所有其他索引进行比较,如果找到匹配项,则对需要的组件的prop返回true。