React 编程思想翻译及学习笔记
第一步:把UI图按组件层次结构拆分开
FilterableProductTable
(橙色): 包含整个例子SearchBar
(蓝色): 接收所有用户输入ProductTable
(绿色): 基于用户输入显示与过滤数据集ProductCategoryRow
(青绿色): 显示每组数据归类标题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个问题。
- 它是从父用过props传过来的吗?如果是它很可以就不是state。
- 它是经常变化的吗?如果不是,它不是state。
- 你可以通过其他的组件中的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}
来反映应用的初始状态。然后,把filterText
和inStockOnly
作为props传给ProductTable
和SearchBar
。最后用这些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