在Redux中最核心的自然是组件,以及组件相关的事件与数据流方式。但是我们在Redux中并没有采用传统的方式在getInitialState()中去初始化数据,而是采用Provider统一处理,省去了开发者不少工作,但是Redux到底如何将state中的数据传递给各组件的呢?还得看看Provider的源。
1.常用数据传递写法
在ReactJS中的数据传递一般采用state和props,而props作为父组件向子组件的主要方式。如:
const TodoList = ({ todos, onTodoClick }) => (
<ul>
{todos.map(todo =>
<Todo
key={todo.id}
{...todo}
onClick={() => onTodoClick(todo.id)}
/>
)}
</ul>
)
以上代码可以看出key, todo数据对象,包括onClick函数都是采用props的方式传递给Todo子组件的。
但是作为统一的数据传递方式Provide,是怎样做的呢。
2.Provider的实现方式。
在我们在调用Provider时,采用的是以下的方式:
const store = createStore(reducer)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
a.首先我们看到的是先创建store对象;
b.然后将store传递给Provider;
c.然后将应用组件做为Provider的子组件。
不过问题又来了:我们并没有看到Provider将store作为props传递给子组件啊。
3.Provider源码实现
打开Provider源码,我们看到Provider的源码实现并不多,除去一些安全性检查的代码外,仅仅剩下面的代码。
export default class Provider extends Component {
getChildContext() {
return { store: this.store }
}
constructor(props, context) {
super(props, context)
this.store = props.store
}
render() {
return Children.only(this.props.children)
}
}
上面的代码可以看出Provider是通过getChildContext的的方式传递给子组件的,并且我们也在connect中看到子组件取数据的过程:constructor(props, context) {
super(props, context)
this.version = version
this.store = props.store || context.store
.......
}
在没有定义props的情况下,通过context直接取得store中的数据,或者说取得context中的数据。而常见的场景一般如下:
<Provider store={store}>
<App />
</Provider>
看来Provider的实现原理,也就知道了它的封装过程和方法,也能更加灵活的运用了