官术网_书友最值得收藏!

Namespaced components

"Shawn, you must have used modules and packages in languages such as Ruby and Java. The idea behind these concepts is to create a namespace hierarchy of code such that the code from one module or package doesn't interfere with another."

"Yes. Is something like this available with React?" Shawn asked.

"Yes. React allows creating components that are namespaced under a parent component so that they don't interfere with other components or global functions."

"We are using very generic names such as Rows and Headings that can be used later in other parts of the app too. So it makes sense to namespace them now, rather than later." explained Mike.

"Agreed. Let's do it right away," Shawn.

"We need to represent the top-level component as custom component rather than using the <table> element."

var RecentChangesTable = React.createClass({
  render: function() {
    return <table>
             {this.props.children}
           </table>;
  } 
});

"Now, we can replace the App component to use RecentChangesTable instead of <table>."

var App = React.createClass({
  render: function(){
    return(<RecentChangesTable>
                <Headings headings = {this.props.headings} />
                <Rows changeSets = {this.props.changeSets} />
           </RecentChangesTable>);
    }
});

"Hang on, Mike. We just replaced <table> with a custom component. All it does is just render this.props.children. How does it get all the headings and rows?" Shawn asked.

"Ah! Nice observation. React, by default, captures all the child nodes between open and close tags of a component in an array and adds it to the props of that component as this.props.children. So we can render it using {this.props.children}. We will get all Headings and Rows as this.props.children in the RecentChangesTable component. The output is the same as before, when we used the <table> tag directly."

"Awesome!" exclaimed Shawn.

"Cool. Let's move on next step by namespacing all other components under RecentChangesTable."

RecentChangesTable.Headings = React.createClass({
  render: function() {
    var headings = this.props.headings.map(function(name) {
      return(<RecentChangesTable.Heading heading = {name}/>);
    });

   return (<thead><tr>{headings}</tr></thead>);
  }
});

RecentChangesTable.Heading = React.createClass({
  render: function() {
    return(<th>
             {this.props.heading}
           </th>);
  }
});


RecentChangesTable.Row = React.createClass({
  render: function() {
    return(<tr>
             <td>{this.props.changeSet.when}</td>
             <td>{this.props.changeSet.who}</td>
             <td>{this.props.changeSet.description}</td>
          </tr>);
  }
});

RecentChangesTable.Rows = React.createClass({
  render: function() {
    var rows = this.props.changeSets.map(function(changeSet) {
      return(<RecentChangesTable.Row changeSet = {changeSet}/>);
    });

    return (<tbody>{rows}</tbody>);
  }
});

"We will also need to update the App component to use namespaced components now."

var App = React.createClass({
  render: function(){
    return(<RecentChangesTable>
                 <RecentChangesTable.Headings headings = {this.props.headings} />
                 <RecentChangesTable.Rows changeSets = {this.props.changeSets} />
               </RecentChangesTable>);
    }
});

"We are now done. Everything is namespaced under RecentChangesTable now", said Mike.

主站蜘蛛池模板: 博兴县| 仁寿县| 望江县| 永寿县| 琼海市| 铜梁县| 渑池县| 青岛市| 阿瓦提县| 綦江县| 曲沃县| 九龙坡区| 富平县| 余姚市| 汨罗市| 屏东市| 淮滨县| 金堂县| 宜兰市| 太原市| 凤阳县| 雷州市| 长武县| 南郑县| 阿瓦提县| 黎城县| 周宁县| 元朗区| 临洮县| 香格里拉县| 城市| 沙河市| 措勤县| 武隆县| 林甸县| 和林格尔县| 天镇县| 连州市| 将乐县| 轮台县| 郑州市|