React专题:不可变属性

转载于 Github
作者博客 博客入口

React是用来解决状态同步的,但它却有一个与this.state并驾齐驱的概念。

这就是this.props

this.props是组件之间沟通的一个接口。

原则上来讲,它只能从父组件流向子组件,但是开发者有各种hack技巧,基本上近亲之间沟通是不成问题的。

this.props

this.props是一个极其简单的接口

你只需要像写HTML标签的属性一样,把它写上去,它就传到了子组件的this.props里面。

不过有几个地方需要注意:

  • 有两个特殊的属性refkey,它们各有用途,并不会传给子组件的this.props
  • 如果只给属性不给值,React会默认解析成布尔值true。
  • 除了字符串,其他值都要用花括号包裹。
  • 如果你把属性给了标签而不是子组件,React并不会解析。

this.props是一个不可变对象

React具有浓重的函数式编程的思想。

提到函数式编程就要提一个概念:纯函数。

纯函数有几个特点:

  • 给定相同的输入,总是返回相同的输出。
  • 过程没有副作用。
  • 不依赖外部状态。

这是一种编程思想。

为什么要提纯函数?因为this.props就是汲取了纯函数的思想。

它最大的特点就是不可变。

this.state不一样的是,this.props来真的。虽然this.state也反对开发者直接改变它的属性,但毕竟只是嘴上说说,还是要靠开发者自己的约束。然而this.props会直接让你的程序崩溃。

加上React也没有this.setProps方法,所以不需要开发者自我约束,this.props就是不可变的。

沟通基本靠吼

父组件给子组件传值

这个无需赘言,最直观的传值方式。

子组件给父组件传值

其实就是利用回调函数的参数传递值。

父组件定义一个方法,将该方法通过props传给子组件,子组件需要给父组件传值时,便传参执行该方法。由于方法定义在父组件里,父组件可以接收到该值。

兄弟组件之间传值

原理和回调函数一样,只不过这里父组件只是一个桥梁。

父组件接收到回调函数的值以后,通过this.setState保存该值,并触发另一个子组件重新渲染,重新渲染后另一个子组件便可以获得该值。

createContext

这是React v16.3.0发布的API。

React为开发者提供了一扇传送门,它就是Context对象。

严格来说,Context早就存在于React中了,不过一直以来都不是正式的API。

终于在v16.3.0转正了。

为什么说Context是一扇传送门?因为它可以跨组件传递数据。不是父子之间的小打小闹哦,而是可以跨任意层级。但是有一个限制,数据只能向下传递,原因就是后面要讲到的单向数据流。

开发者通过createContext创建一个上下文对象(React特别喜欢create),然后找一个顶级组件作为Provider。接下来就可以在任意下级组件消费它提供的数据了。

旧的Context存在一个问题,如果接收组件的shouldComponentUpdate生命周期钩子返回false,则它不会接收到Context中的数据,因为它是通过this.props一级一级往下传的。

而新的Context采取的是订阅发布模式,所以不存在这个问题。

实际上react-redux库的Provider组件内部就是使用了旧的Context API,不过redux做了一些优化。

单向数据流

水往低处流,这是自然规律。

React通过描述状态来控制UI的表达,这就涉及到UI的更新机制。

状态除了内部状态之外,肯定有一些状态是要组件之间共享的,所以,一旦一个组件的状态更新了,可能会牵扯到很多组件的更新,框架的更新机制必将变的异常复杂。

但是回归到水的意象,如果状态的流向是单向的,而且是自上往下流动,这就变的非常符合直觉,而且更新机制可以做到极简:我更新,则我的所有下级也更新。

这就是this.props的思想源头。

它虽然叫props,但它也是状态,只不过是共享的状态。

它只能自顶向下流动。

内部不能改变this.props

某个props的源头更新了,则流经的所有组件都要更新,除非开发者手动禁止。

脉络清晰,this.props才是赋予了React血液的东西。

关于React摒弃了表单双向数据绑定的问题,它只是想把单向数据流做的更彻底一点。其实表单的状态,归根结底是组件内部的状态,跟单向数据流无关。

什么是双向数据绑定?就是表单输入,与之绑定的变量自动获取到输入的值,变量的值改变,与之绑定的表单的值随即改变,两种流向都自动绑定了。

但其实双向数据绑定不就是value的单向绑定加onChange事件监听么!React也可以通过两步做到。

总结:双向数据绑定不影响单向数据流,React也可以实现双向的同步。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复