React组件开发流程——利用React构建简单的可检索产品数据表
Posted 刻刻帝丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React组件开发流程——利用React构建简单的可检索产品数据表相关的知识,希望对你有一定的参考价值。
tip:有问题或者需要大厂内推的+我脉脉哦:丛培森 ٩( ‘ω’ )و
【本文源址:http://blog.csdn.net/q1056843325/article/details/54755521 转载请添加该地址】
今天就是春节了,祝各位鸡年大吉,心想事成
感觉这两天错过了好几个亿
净往外赔钱了~马云爸爸才给了我2.08. 心塞
不过咱也算是参加过一个两亿的项目了
昨晚发现博客还增加了30+访问流量
没想到除夕夜还有这么多努力的人. 佩服 d===( ̄▽ ̄*)b
好了废话不多说
使用React构建可搜索产品数据表
是React官网上的一个demo,它不是很难
不过却能够很好的映射React的开发流程
而且把我们常用的语法基本都涉及了
可以让我们对于React有更进一步的理解
React官方传送门:Thinking in React
#UI与JSON
首先我们从我们的UI设计师那里拿到了UI模拟图和JSON-API
[
category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football",
category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball",
category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball",
category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch",
category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5",
category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"
];
category是产品类别
price是产品价格
stocked是有无库存
name是产品名称
#拆分UI视图
首先我们要做的第一项工作就是拆分UI
把它们拆解成一个个组件,组件中还有子组件
并且赋给它们名字
这个UI可以拆分成五个组件
- FilterableProductTable (黄色)
完整的产品表 - SearchBar (深蓝色)
用户输入部分 - ProductTable (绿色)
产品完整展示部分 - ProductCategoryRow (天蓝色)
产品类别标头 - ProductRow (红色)
产品信息
当然你也可以在细拆把ProductTable中的Name和Price拆出来
不过我觉得没必要搞得这么复杂
组件层次关系如下:
- FilterableProductTable
- SearchBar
- ProductTable
- ProductCategoryRow
- ProductRow
#构建静态版本
静态的版本也就是页面最初应该显示的版本
构建它不需要复杂的想法,只是代码多了点
官网上的文档是这样说的
In simpler examples, it’s usually easier to go top-down,
and on larger projects, it’s easier to go bottom-up and write tests as you build
意思就是像我们这样简单的例子中
通常由顶级层次组件向下来写更简单一些
而在大型的项目中
最佳实践是从下级层次往上写并且要做必要的测试
那在这里的demo我们就从FilterableProductTable组件开始写
var PRODUCTS = [
category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football',
category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball',
category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball',
category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch',
category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5',
category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'
];
var FilterableProductTable = React.createClass(
render: function()
return (
<div>
<SearchBar/>
<ProductTable products=this.props.products/>
</div>
)
);
var SearchBar = React.createClass(
render: function()
return (
<div>
<input type="text"/><br/>
<input type="checkbox"/>Only show products in stock<br/><br/>
</div>
)
);
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>
<td><strong>Name</strong></td>
<td><strong>Price</strong></td>
</tr>
</thead>
<tbody>
rows
</tbody>
</table>
)
);
var ProductCategoryRow = React.createClass(
render: function()
return (
<tr>
<td><strong>this.props.category</strong></td>
</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>
)
);
ReactDom.render(
<FilterableProductTable products=PRODUCTS/>,
document.getElementById('root')
)
很好的体现了React单向数据流的特点
将JSON数据交给父级
然后父级再讲数据传递下去
这里比较关键的代码就是ProductTable中的这部分了
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;
);
利用了数组的形式将静态列表的组件项存储下来
使用变量lastCategory,当当前遍历的product中category与lastCategory不同时
就向数组中添加ProductCategoryRow组件
#售罄产品过滤
我们先来考虑点击那个复选框来重置是否显示售罄产品过滤
很容易的就可以想到必须要设置一个状态
这个状态就是是否只显示有库存的产品(或者不显示售罄产品)
然后为复选框绑定change事件改变状态
var FilterableProductTable = React.createClass(
getInitialState: function()
return
inStockOnly: false
,//设置初始状态:产品默认展示全部
checkHandler: function()
this.setState(
inStockOnly: !this.state.inStockOnly
);
,//复选框要绑定的事件处理函数:改变inStockOnly状态
render: function()
return (
<div>
<SearchBar checkHandler=this.checkHandler/> //将事件处理函数作为数据传递给子级
<ProductTable products=this.props.products inStockOnly=this.state.inStockOnly/>
//将状态state作为属性props传递给子级
</div>
)
);
var SearchBar = React.createClass(
render: function()
return (
<div>
<input type="text"/><br/>
<input type="checkbox" onChange=this.props.checkHandler/>Only show products in stock<br/><br/>
//为复选框绑定change事件处理函数
</div>
)
);
var ProductTable = React.createClass(
render: function()
var rows = [];
var lastCategory = null;
var products = this.props.inStockOnly ?
this.props.products.filter(function(product)
return product.stocked;
) : this.props.products;
//通过判断状态inStockOnly来决定是否过滤products数组
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>
<td><strong>Name</strong></td>
<td><strong>Price</strong></td>
</tr>
</thead>
<tbody>
rows
</tbody>
</table>
)
);
#关键字过滤产品
进度已经过去一大半了
剩下一个问题就是我们在输入框中输入字符时
同样需要对产品进行“过滤”
现在我们需要另外的状态——输入框字符改变
还需要一个事件处理函数来改变这个状态
var FilterableProductTable = React.createClass(
getInitialState: function()
return
inStockOnly: false,
filterText: '' //表示输入框中字符
,
checkHandler: function()
this.setState(
inStockOnly: !this.state.inStockOnly
);
,
textHandler: function(text)
this.setState(
filterText: text
);
, //输入框字符改变状态随之改变,但是还不能获取输入框中字符,所以设置一个参数test
render: function()
return (
<div>
<SearchBar checkHandler=this.checkHandler textHandler=this.textHandler/>
//将事件处理函数作为数据传递给SearchBar组件
<ProductTable products=this.props.products inStockOnly=this.state.inStockOnly filterText=this.state.filterText/>
//将filterText状态传递给ProductTable组件
</div>
)
);
var SearchBar = React.createClass(
Handler: function()
this.props.textHandler(this.refs.input.value);
, //为了将获取的输入框内字符传入textHandler作为参数,外部包装一个函数
render: function()
return (
<div>
<input type="text" ref="input" onChange=this.Handler/><br/>
// 绑定change事件处理函数
<input type="checkbox" onChange=this.props.checkHandler/>Only show products in stock<br/><br/>
</div>
)
);
var ProductTable = React.createClass(
render: function()
var rows = [];
var lastCategory = null;
var products = this.props.products;
var inStockOnly = this.props.inStockOnly;
var filterText = this.props.filterText;
products = inStockOnly ?
products.filter(function(product)
return product.stocked;
) : products;
products = filterText ?
products.filter(function(product)
return product.name.indexOf(filterText) !== -1;
) : products;//通过字符限制一步过滤
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>
<td><strong>Name</strong></td>
<td><strong>Price</strong></td>
</tr>
</thead>
<tbody>
rows
</tbody>
</table>
)
);
#完整版本
完整的脚本代码如下
var React = require('react');
var ReactDom = require('react-dom');
var PRODUCTS = [
category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football',
category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball',
category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball',
category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch',
category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5',
category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'
];
var FilterableProductTable = React.createClass(
getInitialState: function()
return
inStockOnly: false,
filterText: ''
,
checkHandler: function()
this.setState(
inStockOnly: !this.state.inStockOnly
);
,
textHandler: function(text)
this.setState(
filterText: text
);
,
render: function()
return (
<div>
<SearchBar checkHandler=this.checkHandler textHandler=this.textHandler/>
<ProductTable products=this.props.products inStockOnly=this.state.inStockOnly filterText=this.state.filterText/>
</div>
)
);
var SearchBar = React.createClass(
Handler: function()
this.props.textHandler(this.refs.input.value);
,
render: function()
return (
<div>
<input type="text" ref="input" onChange=this.Handler/><br/>
<input type="checkbox" onChange=this.props.checkHandler/>Only show products in stock<br/><br/>
</div>
)
);
var ProductTable = React.createClass(
render: function()
var rows = [];
var lastCategory = null;
var products = this.props.products;
var inStockOnly = this.props.inStockOnly;
var filterText = this.props.filterText;
products = inStockOnly ?
products.filter(function(product)
return product.stocked;
) : products;
products = filterText ?
products.filter(function(product)
return product.name.indexOf(filterText) !== -1;
) : products;
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>
<td><strong>Name</strong></td>
<td><strong>Price</strong></td>
</tr>
</thead>
<tbody>
rows
</tbody>
</table>
)
);
var ProductCategoryRow = React.createClass(
render: function()
return (
<tr>
<td><strong>this.props.category</strong></td>
</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>
)
);
ReactDom.render(
<FilterableProductTable products=PRODUCTS/>,
document.getElementById('root')
)
UI视图切分为组件模块
将JSON数据放入父级组件
再将数据props流入子级组件
设置状态位,然后通过事件处理函数改变状态state
state改变,触发DOM的不断渲染
这个例子诠释了React的组件化、单向数据流的特点
以上是关于React组件开发流程——利用React构建简单的可检索产品数据表的主要内容,如果未能解决你的问题,请参考以下文章