单向数据流与双向数据绑定的理解
React的设计/早期 angular 等 mvvm 框架的对比
数据流
数据在组件之间的流动
React 中的数据流
遵循从上到下的数据流向,即单向数据流。
单向数据流并非 “单向绑定”,甚至单向数据流与绑定没有“任何关系”。
对于React来说,单向数据流(从上到下)与单一数据源这两个原则,限定了React中要想在一个组件中更新另一个组件的状态(类似于
Vue
的平行组件传参,或者是子组件向父组件传递参数)
如果想改变父级的状态,需要进行状态提升。即将状态提升到他们最近的祖先组件中。子组件中
onChange
了状态,触发父组件状态的变更,父组件状态的变更,影响到了另一个组件的显示(因为传递给另一个组件的状态变化了,这一点与Vue
子组件的$emit()
方法很相似)。
在 React
中,数据是单向流动的,是从上向下的方向,即从父组件到子组件的方向。state
和 props
是其中重要的概念,如果顶层组件初始化 props
,那么 React
会向下遍历整颗组件树,重新渲染相关的子组件。其中 state
表示的是每个组件中内部的的状态,这些状态只在组件内部改变。
把组件看成是一个函数,那么他接受 props
作为参数,内部由 state
作为函数的内部参数,返回一个虚拟 dom
的实现。
知乎大V(counterxing)
我认为单向数据流的好处在于所有的状态改变(mutation
)可追溯。
举个例子,父组件维护了一个状态,假设子组件可随意更改父组件甚至祖宗组件的状态,那各组件的状态改变就会变得难以追溯,父组件的状态也可能被子组件意外修改而不可察觉。
而单向数据流保证了父组件的状态不会被子组件意外修改如果要修改,只能通过在子组件中 dispatch
一个 action
来对全局状态修改,全局状态在通过 props
分发给子组件;又或是调用父组件的方法;又或是发事件,这些操作是肉眼可见且可控的(用函数式来说,保证了组件就是无副作用的纯函数),不至于造成状态总被意外修改而导致难以维护的情况。
简单的理解
一:单向数据流
单向数据流的意思是指数据的改变只能从一个方向修改。
举个栗子:如一个父组件有两个子组件,分别为1和2。父组件向子组件传递数据,两个组件都接收到了父组件传递过来的数据,在组件1中修改父组件传递过来的数据,子组件2和父组件的值不会发生变化。这就是单向的数据流,子组件不能直接改变父组件的状态。但是如果父组件改变相应的数据,两个子组件的数据也会发生相应的改变。
二:双向数据绑定
由 MVVM
框架实现,MVVM
的组成:View,ViewModel,Model
。其中 View 和 Model
不能直接通信,要通过 ViewModel
来进行通信。
举个栗子:例如,当 Model
部分数据发生改变时,由于 vue
中 Data Binding
将底层数据和 Dom
层进行了绑定,ViewModel
通知 View
层更新视图;当在视图 View
数据发生变化也会同步到Model
中。View
和 Model
之间的同步完全是自动的,不需要人手动的操作 DOM
。
自己的理解
单向数据流
- 单方向改变数据
- 父子之前,父传数据给子;子不能直接改变父级的数据;在
react
中,可以通过onChange
这种回调方式去修改数据 - 如果把数据看成一个环,这个环其实是断开的,交由开发者用
callback
或者用其它状态框架去做管理,连接数据环
双向数据流
- 父子之间改变数据 可以是正向/反向/双向
- 如果建立了双向的数据绑定,父级数据 改变会影响子级;同理,子级状态改也会反向影响父级
- 从旁观者角度看:父/子都能直接改变数据
- 从环的角度分析,这个环在确定绑定关系为双向;并且,已经做好数据绑定的情况下,环是封闭的,调试难度确实会大一些