Time: 2019-08-18
Provider组件与connect方法
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import store from "./store";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
Provider
组件使得应用可在全局访问store
。
connect方法
将组件与store
联系起来,不用setState
触发组件更新。
Action
action
是把数据从应用传到store
的有效载荷。是store
数据的唯一来源。
一般传递action
的方式:
store.dispatch()
action用于描述发生了什么,使用reducers来按照action更新state,store是联系三者的对象。
Store
职责:
- 维持应用的 state;
- 提供
getState()
方法获取 state; - 提供
dispatch(action)
方法更新 state; - 通过
subscribe(listener)
注册监听器; - 通过
subscribe(listener)
返回的函数注销监听器。
根据已有的reducer
创建store
。
通过combineReducers()
将多个reducer
合并为一个总的,然后用createStore(rootReducer)
创建store
。
createStore
可以接收第二个参数,用于设置state
的初始状态。
需要区分store
的state
和组件的状态。
Redux生命周期
store.dispatch(action)
可以在任何地方调用 store.dispatch(action)
,包括组件中、XHR 回调中、甚至定时器中。
-
store
调用传入的reducer
函数,reducer
函数接收两个参数,当前状态和action
。
reducer
是纯函数。
- 根
reducer
会合并多个子reducer
的输出结果,形成单一的状态树,这个就是应用的下一个state。 -
store.subscribe(listener)
,所有订阅的监听器都会触发,获取当前状态:store.getState()
此时只是store
的状态,为了更新UI,用store
的状态数据来更新组件状态。
如果你使用了 React Redux 这类的绑定库,这时就应该调用 component.setState(newState)
来更新。
展示组件 | 容器组件 | |
---|---|---|
作用 | 描述如何展现(骨架、样式) | 描述如何运行(数据获取、状态更新) |
直接使用 Redux | 否 | 是 |
数据来源 | props | 监听 Redux state |
数据修改 | 从 props 调用回调函数 | 向 Redux 派发 actions |
调用方式 | 手动 | 通常由 React Redux 生成 |
容器组件
技术上讲,容器组件就是使用 store.subscribe()
从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。
可以手工来开发容器组件,但建议使用 React Redux 库的 connect()
方法来生成。
容器组件关注的是将表现层连接到数据。
表现层组件通过props
获取数据。
当用户想将某个表现组件和数据相连时,可以将组件包裹到容器中。
Q: 容器中的数据如何获取?从store状态映射到组件,store是全局,通过上下文获取。
使用connect
使用 connect()
前,需要先定义 mapStateToProps
这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
容器组件的职责:
- 读取state
- 分发action
定义 mapDispatchToProps()
方法接收 dispatch()
方法并返回期望注入到展示组件的 props 中的回调方法。
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case 'SHOW_COMPLETED':
return todos.filter(t => t.completed)
case 'SHOW_ACTIVE':
return todos.filter(t => !t.completed)
case 'SHOW_ALL':
default:
return todos
}
}
const mapStateToProps = state => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
}
这里的mapStateToProps
和mapDispatchToProps
名称可以自定义。
最后,使用 connect()
创建 VisibleTodoList
,并传入这两个函数。
import { connect } from 'react-redux'
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
export default VisibleTodoList
从以下几个地方设定:
- 展示组件
- 容器组件
- reducers
- actions
初始状态写在reducers中,reducers会接收初始状态,并分发action。
容器组件会为组件绑定数据和回调函数,回调函数可以在组件的任何地方通过props.xx
调用。
为什么传递函数给组件
使用store
时,我们假定组件的状态全交给redux
来管理了。那么,修改store
会触发UI的重新渲染。所以容器组件需要将能够修改store
的函数传递到组件,让组件在合适的情况下调用。
改变store
的唯一方式是分发行为,所以mapDispatchToProps
就是干这件事情:将分发行为的函数作为props
传递给组件。
网友评论