第一步:把UI图按组件层次结构拆分开

  1. FilterableProductTable (橙色): 包含整个例子
  2. SearchBar (蓝色): 接收所有用户输入
  3. ProductTable (绿色): 基于用户输入显示与过滤数据集
  4. ProductCategoryRow (青绿色): 显示每组数据归类标题
  5. ProductRow (红色): 显示每一行数据

层次结构如下:

  • FilterableProductTable

    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

第二步:用React做出一个静态版的UI

现在你已经有了层次结构,是时候要实现应该了,最简单的方法就是用你的数据模型来做一个版本然后渲染UI但不需要交互。最好就是把过程解偶开,只需要写不需要想太多交互的东西。

建的时候,你将要想用props传数据的方式来重用别的组件。props是一种数据由父传子的方式。如果你熟悉state的概念,不要只用state来做静态版本。因为它只用来做交互,即数据经常改变时用上。

你可以由上而下或者由下而上来做,即你可以从最高层FilterableProductTable或者由最低层ProductRow开始。但通常,简单项目一般是由上而下;大型项目,则由下而上更好,并要编写测试。

最后,你将有一个可以重用的组件库来渲染数据模型。组件只有render()方法,因为它只是一个静态版本。最高层FilterableProductTable将负责接收数据模型作为prop使用。如果你修改数据模型,再调用ReactDOM.render()就可以更新到UI。非常简单就能看到你的UI更新了什么和哪里做了修改,因为React是通过单向数据流或者叫单向数据绑定来同步数据与UI并且速度非常快。

第三步:识别出最小并完整的UI状态

思考我们例子中所有数据碎片. 我们有:

  • 初始列的所有产品
  • 搜索输入框文字内容
  • 勾选框状态
  • 过滤后的产品列表

那让我们看看哪个是可以用作state。简单的对这些数据问3个问题。

  1. 它是从父用过props传过来的吗?如果是它很可以就不是state。
  2. 它是经常变化的吗?如果不是,它不是state。
  3. 你可以通过其他的组件中的state或者props来计算到它吗?如果是,它就不是state。

初始列的所有产品是通过props传进来的,所以它不是state。搜索输入框文字内容和勾选框状态非常似state,因为他们可以经常改并且不能从其他组件计算得到。最后,过滤后的产品列表不是state,因为它是可以通过搜索输入框文字内容和勾选框状态结合初始列的所有产品计算出来的。

所以最后,我们的state是:

  • 搜索输入框文字内容
  • 勾选框状态

第四步:识别你的state将寄生于哪里。

好,现在我们已经识别出应用的state集。下一步,我们需要识别哪些组件修改或者拥有这些state

记住:React是单向数据流结构。它可能不会马上清晰是哪个组件拥有什么state。 这对新手来说经常是最有挑战性的部分, 因此要跟着这些步骤来弄清楚:

对于你的应用中的每一个state:

  • 弄清楚每个组件基于这个state渲染些什么。
  • 找一个共同宿主组件(一个所有组件之上的组件在结构上需要这个state)。
  • 要么是这个共同宿主组件,要么是另一个在层次之上的组件应该拥有这个state。
  • 如果你找不到这个组件,可以为了用来存储state去在结构或者层次之上新建一个组件来做这事。

让我们用这策略来应该到我们的应用上吧:

  • ProductTable 需要基于state来过滤产品列表, SearchBar 需要显示搜索文字和勾选状态
  • 它们共同宿主是 FilterableProductTable
  • 概念上过滤内容值和勾选值寄生于 FilterableProductTable绝对是可以的。

好,那我们就这样做吧。首先,为FilterableProductTable增加一个getInitialState()方法,返回值是{filterText: '', inStockOnly: false}来反映应用的初始状态。然后,把filterTextinStockOnly 作为props传给ProductTableSearchBar。最后用这些props来过滤ProductTable 的行和设置ProductTable 中表单的值。

你可以开始看到你的应该将如何表现:设置filterText 为"ball"并刷新页面。你应该可以看到数据表已经正确更新。

第五步:添加反向数据流

如果你尝试去在这版本上输入或者打勾 ,你将看到React会忽略你的输入。这是有意为之,因为我们已经设了输入框的 prop值总是等于FilterableProductTable 传过来的state值。

React使得数据流 准确地容易的明白你的程序如何工作,但比传统的双向数据绑定需要写得更多一点 代码。React提供一个叫ReactLink 的插件让这模式使用起来与双向数据绑定一样式 方便,但这文章的目的,是要保持所有东西都清晰。

如果你尝试去在这版本上输入或者打勾 ,你将看到React会忽略你的输入。这是有意为之,因为我们已经设了输入框的 prop值总是等于FilterableProductTable传过来的state值。

让我们想想我们要些什么。我们想要确保无论何时用户改变了表单,我们 就更新state值去反映用户输入。既然组件应该只更新他们自己的state,那么无论 何时state应该更新时,FilterableProductTable将传一个回调函数给SearchBar 并触发它。我们可以用输入框的onChange事件去接收它。然后 FilterableProductTable传来的回调函数将执行setState()函数,之后我们的应 用将被更新。

虽然这样听起来比较复杂,但也就那么几行代码。你的数据如何在应用中流转将会很清晰 。

RunJS源码:http://runjs.cn/code/cgfurbyq

引用自:http://facebook.github.io/react/docs/thinking-in-react.html

React 编程思想翻译及学习笔记的更多相关文章

  1. Oracle User Management FAQ翻译及学习笔记

    转载 最近了解到AME 的东西,很迫切,先转载一篇 [@more@] Oracle User Management FAQ翻译及学习笔记 写在前面 本文主要是翻译的英文版的Oracle User Ma ...

  2. 《C#并发编程经典实例》学习笔记—2.7 避免上下文延续

    避免上下文延续 在默认情况下,一个 async 方法在被 await 调用后恢复运行时,会在原来的上下文中运行. 为了避免在上下文中恢复运行,可让 await 调用 ConfigureAwait 方法 ...

  3. 《C#并发编程经典实例》学习笔记—3.1 数据的并行处理

    问题 有一批数据,需要对每个元素进行相同的操作.该操作是计算密集型的,需要耗费一定的时间. 解决方案 常见的操作可以粗略分为 计算密集型操作 和 IO密集型操作.计算密集型操作主要是依赖于CPU计算, ...

  4. 《Swift程序设计语言》中国翻译和学习笔记page23

    ·<The Swift Programming Language>中文翻译及读书笔记,附件中为英文原版教程 因21页之前内容和技术关系不大,不做翻译整理,从第21页開始 · 页 1 本页主 ...

  5. 《C#并发编程经典实例》学习笔记-第一章并发编程概述

    并发编程的术语 并发 同时做多件事情 多线程 并发的一种形式,它采用多个线程来执行程序. 多线程是并发的一种形式,但不是唯一的形式. 并行处理 把正在执行的大量的任务分割成小块,分配给多个同时运行的线 ...

  6. 《C#并发编程经典实例》学习笔记-关于并发编程的几个误解

    误解一:并发就是多线程 实际上多线程只是并发编程的一种形式,在C#中还有很多更实用.更方便的并发编程技术,包括异步编程.并行编程.TPL 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并 ...

  7. 《Objective-C高级编程》の内存管理の学习笔记

    此日志用于记录下学习过程中碰到的问题 转载请注明出处: http://www.cnblogs.com/xdxer/p/4069650.html <Objective-C高级编程> 人民邮电 ...

  8. 浅谈React编程思想

    React是Facebook推出的面向视图层开发的一个框架,用于解决大型应用,包括如何很好地管理DOM结构,是构建大型,快速Web app的首选方式. React使用JavaScript来构建用户界面 ...

  9. 读《Java并发编程的艺术》学习笔记(一)

    接下来一个系列,是关于<Java并发编程的艺术>这本书的读书笔记以及相关知识点,主要是为了方便日后多次复习和防止忘记.废话不多说,直接步入主题: 第1章  并发编程的挑战 并发编程的目的是 ...

随机推荐

  1. laravel数据库迁移(三)

    laravel号称世界上最好的框架,数据库迁移算上一个,在这里先简单入个门: laravel很强大,它把表中的操作写成了migrations迁移文件,然后可以直接通过迁移文件来操作表.所以 , 数据迁 ...

  2. UIAlertController

    楼主在整理项目的警告,于是乎你懂的. 然后自己整理了一下以后方便自己忘了之后能及时找到它 关于UIAlertController .h文件的解析 /** 关于UIAlertController的解析 ...

  3. 使用php+swoole对client数据实时更新(下)

    上一篇提到了swoole的基本使用,现在通过几行基本的语句来实现比较复杂的逻辑操作: 先说一下业务场景.我们目前的大多数应用都是以服务端+接口+客户端的方式去协调工作的,这样的好处在于不论是处在何种终 ...

  4. Angularjs2 入门

    1.创建文件夹 mkdir angular2-app cd angular2-app 2.配置Typescript 需要通过一些特殊的设置来指导Typesript进行编译.新建一个 tsconfig. ...

  5. HTML5的File API读取文件信息

    html结构: <div id="fileImage"></div> <input type="file" value=" ...

  6. 静态界面传值javascript

    一:JavaScript静态页面值传递之URL篇能过URL进行传值.把要传递的信息接在URL上.Post.htm 复制代码代码如下: <input type="text" n ...

  7. Repeater、地址栏传值、Response--2016年12月30日

    Repeater  Repeater支持以下5种模板       ● ItemTemplate : 对每一个数据项进行格式设置 [Formats each item from the data sou ...

  8. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

  9. SQL批量增加修改数据

    insert into A表(字段1,字段2) select 字段1,字段2 From B表 [注:字段类型.字段数应相同] --批量进行修改ID值 declare @i int begin )) F ...

  10. 【webGL】插件的使用的,实现一个鼠标动画的盒子

    准备工作: 1.stat.js stat.js是Three.js的作者Mr. Doob的另一个有用的JavaScript库.很多情况下,我们希望知道实时的FPS信息,从而更好地监测动画效果.这时候,s ...