React, 在我看来, 是使用JavaScript构建大型、快速web应用的一种重要手段。我们已经将其广泛使用在FaceBook和Instagram中。
React有许多重要之处、其中之一就是使用React创建app时的思考方式。下面我将向你展示开发一个可搜索的数据列表产品的思考过程。
从素材开始
假设我们已经已经有了JSON API和来自设计师的素材。我们的设计师显然不够牛,因为素材看起来像这样:
我们的JSON API返回些数据,如下所示:
第1步: 将UI切分程组件层次
你需要做的第一件事就是在素材中的每个组建(还有子组件)的周围画些格子并且给它们命名。如果你在和一个设计师合作,他们也许已经做好了,因此和他们交流下!他们的Photoshop图层名也许最终就是你的React组件名。
但是你如何去划分自己的组件呢?仅仅和你去创建一个方法或者对象的技术一样。其中一种技术叫单一责任原则,意思是,理论上一个组件只做一件事情。如果将来它要扩展,它就需要被分解成一些更小的子组件。
因为你要经常将JSON数据模型展示给用户,你会发现如果你的建模正确了,相应的你的UI(也包括你的组件结构)也会很好。这是因为UI和数据模型倾向于遵循同样的信息结构,这意味把UI分割成组件的工作非常重要。将它分割成那些能够准确展示你的数据模型的组件就行。
这里你能看到,在我们的小应用中有五个组件。我已经列出了每个组件想展示的数据:
1. 产品过滤表(橙色):包含了整个例子
3. 产品列表(绿色): 展示和过滤那些基于用户输入的数据集
4. 产品目录行(青绿色): 展示目录头
5. 产品行: 展示一种产品
如果你在看产品列表,你将会看到表头(包含‘Name’和‘Price’标签)不是它自己的组件。这仅仅是选择的问题,并且无论哪种选择都会有争议。在这个例子中,我把表头作为产品列表的一部分,是因为它也是用来渲染数据集合,而这些集合是产品列表的响应。但是,如果这个头部变得复杂(如果我们需要增加些提示用来排序),那么当然应该创建个它自己的“产品列表头”组件。
现在,我们明确了我们素材中的组件,让我们将他们安装结构来排列。这很简单。出现在素材中另一个组件中的组件,在结构中应该被当做子节点。
第2步: 用React建立一个静态版本
JavaScript7
var ProductCategoryRow = React.createClass({ render: function() { return (<tr><th colSpan="2">{this.props.category}</th></tr>); } }); var ProductRow = React.createClass({ render: function() { var name = this.props.product.stocked ? this.props.product.name : <span style={{color: 'red'}}> {this.props.product.name} </span>; return ( <tr> <td>{name}</td> <td>{this.props.product.price}</td> </tr> ); } }); var ProductTable = React.createClass({ render: function() { var rows = []; var lastCategory = null; this.props.products.forEach(function(product) { if (product.category !== lastCategory) { rows.push(<ProductCategoryRow category={product.category} key={product.category} />); } rows.push(<ProductRow product={product} key={product.name} />); lastCategory = product.category; }); return ( <table> <thead> <tr> <th>Name</th> <th>Price</th> </tr> </thead> <tbody>{rows}</tbody> </table> ); } }); var SearchBar = React.createClass({ render: function() { return ( <form> <input type="text" placeholder="Search..." /> <p> <input type="checkBox" /> {' '} Only show products in stock </p> </form> ); } }); var FilterableProductTable = React.createClass({ render: function() { return ( <div> <SearchBar /> <ProductTable products={this.props.products} /> </div> ); } }); var PRODUCTS = [ {category: 'Sporting Goods',price: '$49.99',stocked: true,name: 'Football'},{category: 'Sporting Goods',price: '$9.99',name: 'Baseball'},price: '$29.99',stocked: false,name: 'Basketball'},{category: 'Electronics',price: '$99.99',name: 'iPod Touch'},price: '$399.99',name: 'iPhone 5'},price: '$199.99',name: 'Nexus 7'} ]; ReactDOM.render( <FilterableProductTable products={PRODUCTS} />,document.getElementById('container') );HTML
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script> <div id="container"> <!-- This element's contents will be replaced with your component. --> </div>现在你已经有了你的组件结构,是时候来完成你的应用了。最简单的办法是创建一个利用了数据模型并且渲染了UI,但是没有交互的版本。最好的办法就是