用React完成点击切换的标签页

一、起首是Showcase

See the Pen react-tabs by Wang Chao (@charleyw) on CodePen.

二、怎样完成

既然用React写,那末它就必定是一个组件,起首斟酌你怎样运用这个组件,也就是这个组件的接口是怎样的。

<TabsControl>
  <Tab name="red">
    <div className="red"/>
  </Tab>
  <Tab name="blue">
    <div className="blue"/>
  </Tab>
  <Tab name="yellow">
    <div className="yellow"/>
  </Tab>
</TabsControl>

这个TabsControl作为父组件,它来掌握Tab的怎样切换,Tab是用来包裹真正要显现的内容的,它的name属性是这个标签页的名字,会被显现在标签页的题目栏上。

三、建立基础元素

依据之前的主意,我们用Tab定义了很多个标签页,我们须要依据这些定义天生标签页的题目栏和内容。

1. 遍历this.props.children动态天生题目栏

this.props.children是React内建的一个属性,用来猎取组件的子元素。由于子元素有多是Object或许Array,所以React供应了一些处置惩罚children的辅佐要领用来遍历:React.Children.map

那末动态天生题目的代码多是这模样的:

React.Children.map(this.props.children, (element, index) => {
    return (<div className="tab-title-item">{element.props.name}</div>)

2. 再用一样要领天生标签页内容

React.Children.map(this.props.children, element => {
    return (element)
})

组合起来就是TabsControl的完成:

let TabsControl = React.createClass({
  render: function () {
    let that = this;
    let {baseWidth} = this.props;
    let childrenLength = this.props.children.length;
    return (
      <div>
        <nav className="tab-title-items">
          {React.Children.map(this.props.children, (element, index) => {
            return (<div className="tab-title-item">{element.props.name}</div>)
          })}
        </nav>
        <div className="tab-content-items">
          {React.Children.map(this.props.children, element => {
            return (element)
          })}
        </div>
      </div>
    )
  }
});

加上一些css就能够看到一个标签页的雏形了。

三、完成标签页切换

这里要涌现React最主要的概念了statestate是一个Javascript的Object,它是用来示意组件的当前状况的,假如用TabsControl举例的话,它的state可所以当前处于激活状况的标签页编号(固然,假如你想的话也能够保留标签页的内容)。
React供应了一个要领setState()让你能够转变state的值。每次挪用setState()都邑触发组件的render(),也就是说会把组件所代表的DOM更新到state所代表的状况。

所以完成切换的症结以下:

  1. state保留当前处于激活状况的标签页的编号

  2. 点击题目的时刻挪用setState()更新激活的标签页编号

  3. render()的时刻,在遍历this.props.children的时刻把编号与state中编号一致的元素标记为active

  4. 用css将非active的元素隐蔽起来

所以代码是如许的:

let TabsControl = React.createClass({
  getInitialState: function(){
    return {currentIndex: 0}
  },
  
  getTitleItemCssClasses: function(index){
    return index === this.state.currentIndex ? "tab-title-item active" : "tab-title-item";
  },
  
  getContentItemCssClasses: function(index){
    return index === this.state.currentIndex ? "tab-content-item active" : "tab-content-item";
  },
  
  render: function(){
    let that = this;
    let {baseWidth} = this.props;
    let childrenLength = this.props.children.length;
    return (
      <div>
        <nav className="tab-title-items">
          {React.Children.map(this.props.children, (element, index) => {
            return (<div onClick={() => {this.setState({currentIndex: index})}} className={that.getTitleItemCssClasses(index)}>{element.props.name}</div>)
          })}
        </nav>
        <div className="tab-content-items">
          {React.Children.map(this.props.children, (element, index) => {
            return (<div className={that.getContentItemCssClasses(index)}>{element}</div>)
          })}  
        </div>
      </div>
    )
  }
});

getInitialState:是组件的初始化状况,默许是第一个标签页处于激活状况。
getTitleItemCssClasses:推断当前标签和state中保留的标签编号是不是一向,是则标识为active
getContentItemCssClasses:同上。
onClick={() => {this.setState({currentIndex: index})}}:标签页题目绑定了点击事宜,每次点击都邑更新state保留的标签页编号,然后触发render()要领重绘标签页。

四、总结

上面一系列的操纵终究的效果都须要用render()来回响反映出来,所以症结点是怎样在render()中运用state来动态天生DOM.

接下来的革新

完成能够滑动的标签页

    原文作者:charleyw
    原文地址: https://segmentfault.com/a/1190000004200481
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞