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
HTML
- 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')
- );
现在你已经有了你的组件结构,是时候来完成你的应用了。最简单的办法是创建一个利用了数据模型并且渲染了UI,但是没有交互的版本。最好的办法就是
- <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>