1. 确定设计稿和数据

设计稿:

数据:

[
{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"}
];

2. 将设计稿UI分组件层级

组件单一功能原则:

即一个组件实现一个功能。

图中,一个颜色是一种组件,按照嵌套关系,可以分为:

FilterableProductTable:

SearchBar:

ProductTable:

ProductCategoryRow

ProductRow

3. 确定需要的state值的个数

原则:

1. 值不是来自与props
2. 值不是一成不变
3. 值不能由其他state和props求得

该示例中,需要数据源的地方有:

1. 查询框的文本 // 会变化;state.filterText
2. 复选框的状态 // 会变化;state.isStock
3. 所有的产品列表数据 // 通过props传入; 无state
4. 过滤后的产品列表数据 //通过1,2,3获得; 无state

4. 确定state的位置-状态提升

通过分析state对应的值作用的范围,state应该位于所有作用区域的父组件;

才能共享state。

从功能分析,1,2的状态会影响列表展示;则其应该位于查询框和列表的父组件;

即组件FilterableProductTable中。

3的状态会影响列表分类ProductCategoryRow和列表项ProductRow,则应该放在他们的父组件;

即组件ProductTable中。

5. 添加反向数据流

即通过触发子组件的事件监听,调用父组件传递过去的函数,从而改变父组件的state的值。

因为state的状态提升,而state又是私有状态,只能通过state所处的组件的函数进行修改。

6. 从下向上编写代码

/*
* @Author: LyraLee
* @Date: 2019-11-08 09:01:58
* @LastEditTime: 2019-11-20 17:32:14
* @Description: 分类数据处理
*/
'use strict'
const products = [
{category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
{category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
{category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
{category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
{category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
{category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];
function ProductRow(props) {
const product = props.product;
const { name } = product;
const renderName = !product.stocked ? <span style={{color: 'red'}}>{name}</span> : name
return (
<tr>
<td>{renderName}</td>
<td>{product.price}</td>
</tr>
)
}
function ProductCategoryRow(props) {
const product = props.product;
return(
<tr>
<th colSpan="2">{product.category}</th>
</tr>
)
}
function ProductTable(props) {
const { filterText, isStockedOnly, products } = props;
// 处理数据的方法!!!需要分类的属性是category,
// 如果数据不是按照该属性排序,那先将其按照category的字段顺序
let lastCategory = null;
let rows = []
products.sort((a,b) => a.category.localeCompare(b.category))
.forEach(product => {
if (!product.name.includes(filterText)) {
return;
}
if (isStockedOnly && !product.stocked) {
return;
}
if (product.category !== lastCategory) {
rows.push(<ProductCategoryRow key={product.category} product={product} />)
}
rows.push(
<ProductRow key={product.name} product={product} />
)
lastCategory = product.category;
}); return (
<table>
<thead>
<tr>
<th>name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
)
}
function SearchBar(props) {
function handleChange (e) {
const { name, type } = e.target;
const value = type === 'checkbox' ? e.target.checked : e.target.value;
props.handleChange(name, value);
}
const { filterText, isStockedOnly } = props;
return(
<div>
<input
name="filterText"
type="text"
value={filterText}
onChange={handleChange}
placeholder="search..."
/>
<p>
<input
name="isStockedOnly"
type="checkbox"
checked={isStockedOnly}
onChange={handleChange}
/>{' '}
Only show products in stock
</p>
</div>
)
}
class FileterableProductTable extends React.Component {
constructor(props) {
super(props);
this.state = {
filterText: '',
isStockedOnly: false
}
}
handleChange = (name, value) => {
this.setState({
[name]: value
})
}
render() {
const { filterText, isStockedOnly } = this.state;
const { products } = this.props;
return(
<React.Fragment>
<SearchBar
filterText={filterText}
isStockedOnly={isStockedOnly}
handleChange={this.handleChange}
/>
<ProductTable
filterText={filterText}
isStockedOnly={isStockedOnly}
products={products}
/>
</React.Fragment>
)
}
} ReactDOM.render(<FileterableProductTable products={products} />, root);

从设计稿到实现React应用(分类数据处理)的更多相关文章

  1. React Native不同设备分辨率适配和设计稿尺寸单位px的适配

    React Native中使用的尺寸单位是dp(一种基于屏幕密度的抽象单位.在每英寸160点的显示器上,1dp = 1px),而设计师使用的是px, 这两种尺寸如何换算呢? 官方提供了PixelRat ...

  2. iPhone 6/6 Plus 出现后,如何改进工作流以实现一份设计稿支持多个尺寸?

    iPhone 6/6 Plus 出现后,如何改进工作流以实现一份设计稿支持多个尺寸? 2014-12-05 09:33 编辑: suiling 分类:iOS开发 来源:知乎(pigtwo)  2 22 ...

  3. iOS设计 - 一款APP从设计稿到切图过程概述

    这篇文章站在GUI设计师的角度概述了APP从项目启动到切片输出的过程,相当于工作流程的介绍.这里写的不是一种规范,只是一种工作方法,加上技术的更新是非常快的,大家在具体工作中,一定要灵活运用. 这里我 ...

  4. 从网易与淘宝的font-size思考前端设计稿与工作流

    本文结合自己对网易与淘宝移动端首页html元素上的font-size这个属性的思考与学习,讨论html5设计稿尺寸以及前端与设计之间协作流程的问题,内容较多,但对你的技术和工作一定有价值,欢迎阅读和点 ...

  5. 从网易与淘宝的font-size思考前端设计稿与工作流 (转)

    从网易与淘宝的font-size思考前端设计稿与工作流   阅读目录 1. 问题的引出 2. 简单问题简单解决 3. 网易的做法 4. 淘宝的做法 5. 比较网易与淘宝的做法 6. 如何与设计协作 7 ...

  6. 学习笔记:只有一套app设计稿(5s尺寸)切出4和4s尺寸以及安卓系统主流尺寸的图

    如何在只有一套app设计稿(5s尺寸)切出4和4s尺寸以及安卓系统主流尺寸的图 转自:http://www.zhihu.com/question/23255417   版权归原作者所有 目前ios手机 ...

  7. 移动端H5页面的设计稿尺寸大小规范-转载自http://www.chinaz.com/design/2015/1103/465670.shtml

    机屏幕尺寸,设计稿应该按照哪一个尺寸作为标准尺寸.现在已经有2K分辨率的手机屏幕了,设计稿是不是也要把宽高跟着最大分辨率来设计.显然不是. 请注意:(以下所有讨论内容和规范均将viewport设定为c ...

  8. 一款APP从设计稿到切图过程全方位揭秘 Mark

    纯干货!一款APP从设计稿到切图过程全方位揭秘   @BAT_LCK:我本身是一名GUI设计师,所以我只站在GUI设计师的角度去把APP从项目启动到切片输出的过程写一写,相当于工作流程的介绍吧.公司不 ...

  9. iPhone 6出现后,如何将一份设计稿支持多个尺寸?

    http://mp.weixin.qq.com/s?__biz=MzA4NTQzNTMwOA==&mid=201174413&idx=3&sn=c3fe5b3459bac288 ...

随机推荐

  1. Python中nonlocal的用法

    class Text: def __init__(self): pass def big(self): n, m = 0, 0 def a(): nonlocal n n += 1 print(n) ...

  2. python3+django报错testserver

    manage.py testserver --addrport 127.0.0.1 报错 查看其它项目 manage.py runserver --addrport 127.0.0.1 正常 查找配置 ...

  3. ALV报表——选择屏幕选项卡

    ALV选择屏幕选项卡 运行效果: 代码: *&--------------------------------------------------------------------* *&a ...

  4. Generator 实现

    Generator 是 ES6 中新增的语法,和 Promise 一样,都可以用来异步编程 // 使用 * 表示这是一个 Generator 函数 // 内部可以通过 yield 暂停代码 // 通过 ...

  5. 解决阿里云OSS The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint的办法

    以前有一个上海节点的存储包,一直使用正常.最近购买了一个全国的存储包,发现在上传文件的时候有这个问题. 尝试了很多办法,还提交了工单,都没有解决. 最后解决办法如下: 1.在阿里云OSS管理控制台下, ...

  6. C#导入Excel表格功能aspx.cs(代码)

    using System; using System.Data; using System.Configuration; using System.Collections; using System. ...

  7. SQL 多并发 多人取号,防止重复取号SQL 办法

    BEGIN TRAN         SELECT  *  from 表明 WITH(HOLDLOCK)        UPDATE 表名 SET 值=1 WHERE 字段=@carrierNo;   ...

  8. C# 弹出层移动

    groupPrint.MouseDown += GroupBox1_MouseDown; #region 弹出层移动        [System.Runtime.InteropServices.Dl ...

  9. shell 实战 -- 基于一个服务启动,关闭,状态检查的脚本

    功能说明: check:检查服务状态,在开启,关闭,状态检查时都会用到这个函数,所以封装起来放到最前面 start:开启服务 stop:关闭服务 fstop:强制关闭 status:检查服务状态 ru ...

  10. activemq BytesMessage || TextMessage

    需求:使用 python 程序向 activemq 的主题推送数据,默认推送的数据类型是 BytesMessage,java 程序那边接收较为麻烦,改为推送 TextMessage 类型的数据 解决方 ...