在所选选项卡上react添加类活动

IT技术 reactjs
2021-05-03 04:14:01

我有以下几点:

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个回答

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

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>

死灵海报在这里。上面的回答很酷!

无论如何,这是带有recompose的 2018 年升级答案styled-components你甚至可以用它制作一个 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 enhancer = compose(
  withState("selectedTabId", "setSelectedTabId", 1),
  withHandlers({
    isActive: props => id => {
      return props.selectedTabId === id;
    },
    setActiveTab: props => id => {
      props.setSelectedTabId(id);
    }
  })
);

const Tabs = enhancer(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"));

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