简单实现react双向绑定

在看Vue.js文档的时候,看到深入响应式原理这一节时,顺便想了想如何模仿Vue.js的双向绑定原理来实现react的双向绑定。

Vue.js的双向绑定中,使用Object.defineProperty来设置属性的setter和getter,从而把属性变为一个observable。于是,是不是也可以使用相同的方法来实现react的绑定呢。

首先,react中改变state需要使用setState来实现:

setState({
  name: "value"
})

我们可以通过Object.defineProperty来改变name属性的setter

Object.defineProperty(this.state, "name", {
  set: newName => {
      this.setState({
        name: newName
      })
  }
})

通过设置之后,我们应该就可以在组件中直接使用

this.state.name = "new Name"

通过上面的思考,为了进一步简化双向绑定的步骤,我们可以写出一个双向绑定的工具函数:

function defineObservableState(this, mState) {
  if (!this.state) this.state = {}
  Object.keys(mState).forEach(key => {
    Object.defineProperty(this.state, key, {
      value: mState[key],
      set: newName => {
        this.setState({
          name: newName
        })
      }
    })
  })
}

这样,我们就可以直接使用

class Home extends React.Component {
  constructor(props) {
    super(props)
    defineObservableState(this, {
      name: "my name"
    })
  }
}

需要注意的是,此时给name赋值,state的改变是异步的。

那么,表单如何绑定变量呢

<input type="text" valueLink={{ value: this.state.name, requestChange: newValue => this.state.name = newValue }} />

从代码中我们看到,valueLink略显冗余,我们来对input进行一层包装

props => (
  <input valueLink={{ value: props.bindValue, requestChange: newValue => props.bindValue = newValue }} ...props />
)

这样就基本实现了react双向绑定的功能。

作为学习中的记录,代码中或许有些不足,欢迎交流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近这部电影很火,大意讲的是一群人包括父女、姐妹、夫妇、情侣、同学还有高管在列车上遇到僵尸,被咬后就会疯狂的传染给...
    浆糊郎中阅读 225评论 0 0
  • 昨晚做了很长的梦,早上醒来时感觉腰疼,无力,乏,不想起床。 梦境有两个,一个场景是我好像在上学,在参加一个...
    塔罗师默默阅读 129评论 0 0