React 中的双向绑定

 

在开发 Nautil 中我想作些不同的尝试。javascript

和主流的 react 生态格格不入,nautil 像是对 react 的反目,但实际上我但愿在现有优秀的 UI 框架上,作一些不同的东西。nautil 基于“观察者模式”,在 react 中实现相似 vue 同样的属性更新的响应式模式,以及今天要讲的双向绑定。html

单向数据流vue

React 推崇单向数据流,组件经过 props 接收数据,控制 UI 展现。当用户对组件进行操做时,在每个操做上,组件调用 props 上传递的函数,并将内部的状态数据做为参数传递给这些回调函数。而这些回调函数,必须修改原来传入的 props 值,才能保证组件的 UI 以新的界面展现。java

单向数据流的好处,是保证了组件的纯粹性,用户不用担忧反作用,并且严格按照 immutable 数据的方式控制 UI 展现。react

双向绑定git

在早期的 angular1.x 版本中,一个 directive 声明 scope 属性为 = 时,angular 会将该属性和外部传入的属性进行双向绑定。外部对应的属性发生变化时,该 directive 内部也会因为对应属性的变化而从新渲染。固然,这也是由于 angular 是脏检查机制,从顶往下全量检查。github

在 vue 中,表单组件 input 等支持 v-model 属性实现双向绑定,这给单向数据流的应用框架提供了一种思路。vue 的实现,其实是用一个 v-model 指令,完成单向的数据传入和 @input 事件响应。而正好由于 vue 基于模板语法,属性路径(keyPath)的使用很是方便,因此 v-model 的实现很是优雅。数组

在 react 中双向绑定app

基于 v-model 的解决思路,一个双向绑定,实质是一个单向数据传入,和一个事件的响应。所以,咱们在 react 中,也能够模拟这种实现。框架

class Input extends Component {
  static props = {
    $value: [String, Function],
  }

  render() {
    const { $value } = this.props
    const [value, reflect] = $value
    return <input type="text" value={value} onChange={e => reflect(e.target.value)} /> } }复制代码

这样的代码很是容易理解。无非是迫使一个 prop 传入的值是一个特定数组结构。

class App extends Component {
  state = {
    value: 'xxx',
  }
  render() {
    return <Input $value={[this.state.value, value => this.setState({ value })]} /> } }复制代码

按照这样的思路,咱们基本能够实现 v-model 在 react 中的运行模式。可是显然,这样还不够简单,有没有更简洁的写法?

在 nautil 中实现了更简单的内部双向绑定操做,可在组件内像 vue 同样,写 this.attrs ++ 这样的语法。若是你感兴趣,不妨一试。

相关文章
相关标签/搜索