使用 React.js 在选项卡上切换类

IT技术 class backbone.js tabs twitter-bootstrap-3 reactjs
2021-04-09 03:13:35

所以我有一个tab-component有 3 个项目:

React.DOM.ul( className: 'nav navbar-nav', 
    MenuItem( uid: 'home')
    MenuItem( uid: 'about')
    MenuItem( uid: 'contact)
)

而在.renderMenuItem

React.DOM.li( id : @props.uid, className: @activeClass, onClick: @handleClick,
    React.DOM.a( href: "#"+@props.uid, @props.uid)
)

每次我单击一个项目时,都会调用一个主干路由器,然后调用tab-component然后调用page-component.

我仍然试图解决这个事实,即基本上是单向数据流。而且我已经习惯了直接操作 DOM。

我想要做的是将.active添加到单击的选项卡中,并确保将其从不活动的选项卡中删除。

我知道 CSS 技巧,您可以在其中使用data-属性并将不同的样式应用于true属性false

骨干路由器已经得到了变量uid并调用了正确的页面。我只是不确定如何最好地在选项卡之间切换类,因为只有一个可以同时处于活动状态。

现在我可以记录选择了哪个选项卡,并切换它们等等。但是 React.js 已经有了这个记录保存功能。

@handleClick你看,我甚至不希望使用的,因为路由器应该告诉tab-component这些人给的className: '.active',我想避免的jQuery,因为React.js并不需要直接的DOM操作。

我已经用@state 尝试了一些东西,但我确信有一种非常优雅的方法可以实现这一点,相当简单,我想我看了一些演示或视频,有人在做这件事。

我真的必须习惯并改变我的思维方式,以react性地思考。

只是寻找一种最佳实践方式,我可以用一种非常丑陋和笨重的方式来解决它,但我喜欢 React.js,因为它非常简单。

3个回答

将状态尽可能向上推到组件层次结构,并props在下面的所有级别上处理不可变的将活动选项卡存储在您的活动选项卡中tab-component并从数据生成菜单项(this.props在本例中)以减少代码重复似乎是有意义的

以下示例的 JSFiddle 工作 + 骨干路由器: http : //jsfiddle.net/ssorallen/4G46g/

var TabComponent = React.createClass({
  getDefaultProps: function() {
    return {
      menuItems: [
        {uid: 'home'},
        {uid: 'about'},
        {uid: 'contact'}
      ]
    };
  },

  getInitialState: function() {
    return {
      activeMenuItemUid: 'home'
    };
  },

  setActiveMenuItem: function(uid) {
    this.setState({activeMenuItemUid: uid});
  },

  render: function() {
    var menuItems = this.props.menuItems.map(function(menuItem) {
      return (
        MenuItem({
          active: (this.state.activeMenuItemUid === menuItem.uid),
          key: menuItem.uid,
          onSelect: this.setActiveMenuItem,
          uid: menuItem.uid
        })
      );
    }.bind(this));

    return (
      React.DOM.ul({className: 'nav navbar-nav'}, menuItems)
    );
  }
});

除了附加类名和公开点击事件之外,MenuItem 几乎可以做的很少:

var MenuItem = React.createClass({
  handleClick: function(event) {
    event.preventDefault();
    this.props.onSelect(this.props.uid);
  },
  render: function() {
    var className = this.props.active ? 'active' : null;

    return (
      React.DOM.li({className: className},
        React.DOM.a({href: "#" + this.props.uid, onClick: this.handleClick})
      )
    );
  }
});
您可以调用setProps通过React.renderComponent调用呈现的根组件在路由更改时,您可以通过调用来设置新的活动选项卡setProps在我的示例中,我将活动菜单项作为状态的一部分,但可以将其移动到道具中以使其成为可能。
2021-05-24 03:13:35
需要明确的是,该.bind()部件确保在其绑定组件上更新propsstate更新?因此,从技术上讲,我是否使用propsstate? 只有在生命周期的哪个时刻我希望能够访问它们才重要。(但肯定将是最好的鸿沟statepropsfuntionally。)还有最后一两件事:setPropssetState两个触发相同的组件的生命周期?
2021-05-28 03:13:35
classSet被贬低。你能更新你的小提琴吗?facebook.github.io/react/docs/class-name-manipulation.html
2021-05-28 03:13:35
谢谢,这对我来说解决了很多问题,但是,我正在处理一个路由器,并且似乎调用: React.renderComponent( TabComponent( uid: 'home' ) ),当 URL 更改时,会触发一系列不应在反应逻辑中全部触发的组件。阅读评论:jsfiddle.net/TrySpace/9a7TA/2
2021-05-31 03:13:35
但技术的一部分,:this.props.active ? 'active' : null;active: (this.state.activeMenuItemUid === menuItem.uid)做的招果然,这种简单的表情...
2021-06-22 03:13:35

您可以尝试react-router-active-componet - 如果您使用 boostrap 导航栏。

您可以尝试将菜单项单击处理程序推送到其父组件。事实上,我正在尝试做一些类似于你正在做的事情......我有一个顶级菜单栏组件,我想使用菜单栏模型来呈现菜单栏和项目。其他组件可以通过添加到菜单栏模型来为顶级菜单栏做出贡献……只需添加顶级菜单、子菜单项和单击处理程序(在添加菜单的组件中)。然后顶级组件将呈现菜单栏 UI,当单击任何内容时,它将使用“回调”组件单击处理程序进行调用。通过使用菜单模型,我可以添加诸如动作/鼠标悬停/非活动等的 css 样式以及图标等。然后顶级菜单栏组件可以决定如何呈现项目,包括鼠标悬停、点击等。