v16之前传值主要通过props一层层从顶层向下传递。或者通过Redux/MobX进行状态分发。
v16之后React提供了Context这样的一个Api。组件嵌套很深的情况下可以用。
看了官网文档以及一些同僚的文档,对此API有了大概的认识。写了个简单地Demo
顶层组件:
import React from 'react'
import Toolbar from './Toolbar'
export const ThemeContext = React.createContext({ type: 'danger' });
export default class ContextDemo extends React.Component {
render() {
let style = { type: 'primary' };
return <ThemeContext.Provider value={style}>
<Toolbar />
</ThemeContext.Provider>;
}
}
个人理解:React.createContext({ type: 'danger' });为我们提供里一个上下文容器。参数为上下文设置的初始值。主要是要将这个容器暴露出去。官网是吧容器抽成一个文件独立出来了。有点Redux里Reducer的意思。然后通过容器的生产者模式提供一个值,即 标签内的value。这样就设置好了容器、初始值、以及要传的值。
中间组件:
import React from 'react'
import ThemedButton from './ThemedButton'
function Toolbar(props) {
// Toolbar 组件接受一个额外的“theme”属性,然后传递给 ThemedButton 组件。
// 如果应用中每一个单独的按钮都需要知道 theme 的值,这会是件很麻烦的事,
// 因为必须将这个值层层传递所有组件。
return (
<div>
<ThemedButton />
</div>
);
}
export default Toolbar
个人理解:这段是直接照官网抄的。没有任何上层的props。因为只是个中间组件,不需要实际的上下文内容来渲染什么东西。所以这段没什么东西。
最下层组件:
import React from 'react'
import { Button } from 'antd'
import { ThemeContext } from './ContextDemo'
export default class ThemedButton extends React.Component {
render() {
return <ThemeContext.Consumer>
{
(style) => <Button type={style.type}>Text</Button>
}
</ThemeContext.Consumer>;
}
}
个人理解:
因为最下层组件需要顶层中的值。所以首先要根据容器构建一个消费者组件。
组件中匿名函数的直接可以取到顶层传过来的值。
主要的一个流程就是这样。
1.顶层组件创建容器以及生产者
2.子组件引入容器构建消费者
好处:这样避免了多层嵌套的时候,每一层都要传props,而且中间层可能还不需要这个玩意儿,写起来就和啰嗦。
弊端:当然也不是说这个方式就完美,官网也说了这东西可能会影响组件的复用。随机应变呗。
网友评论