React中的Context
未使用Context
Context提供了层级组件间传值的方式,对于嵌套层级较深的组件,不需要再层层传递属性。
比如有这样三个组件,页面渲染了Father组件,Father组件引用了Middel组件,Middle组件引用了Son组件。于是,最终页面渲染出了Son组件的内容:
现在,如果想要从Father组件传值给Son,更改Father组件的内容,为Middle增加一个属性:
修改Son组件,接收属性值并打印:
仅做此修改显然是不行的,Son组件不可能接收到值,这很容易理解。想要实现效果,必须在Middle组件中加一个属性用于传递,于是,修改后的完整代码像这样:
Middle组件仅仅为了将父组件的属性传递给子组件,就必须在自己的属性列表中增加value属性,此外无其它意义。如果组件嵌套多层,这就是一个亟待解决的问题。
Context正是优质的解决方案。
使用了Context
回到最初的代码,与下面的示例做对比:
可见,Context本身也是一个组件,createContext()创建了一个Context组件,然后分别在父子组件中调用Provider和Consumer。使用Context组件,Middle无需任何更改。
高阶组件与Context
如果频繁使用Context.Consumer,显得有些繁琐,可以使用高阶组件让这一操作变得简洁:
这里定义了一个处理函数WithValue(),接收一个组件,将Context中的属性赋予该组件,并返回。
这样,每当想要使用value属性,只要调用WithValue()函数进行处理即可。
装饰器与高阶组件
结合装饰器可以更加优雅的使用高阶组件。
因为JavaSctipt中的装饰器不允许修饰函数,所以需要将Son组件更改为class形式:
这里的代码包含了导入模块的语句。装饰器是较新的语法特性,浏览器环境自Babel 6.0不再更新,最好在node环境中测试。
有了语法糖的加持,使用Context的代码更加简洁。