Redux 和 React 之间没有关系。Redux 支持 React
、Angular
、Ember
、jQuery 甚至纯 JavaScript
。尽管如此,Redux 还是和 React 和 Deku 这类库搭配起来用最好,因为这类库允许你以 state 函数的形式来描述界面,Redux 通过 action 的形式来发起 state 变化。
下面我们来看一个使用 react-redux 完成计数器的案例:
最终实现的效果:点击左边的加号按钮,中间的数字加2(可以自定义参数);点击右边的减号按钮,中间的数字减1;
目录结构:
├── index.jsx //入口文件
├── Count.jsx //显示页面内容的组件
├── Button.jsx //按钮组件
├── store.js //创建一个store,用来集中管理state dispatch action
├── reducer.js //业务逻辑层,对数据进行操作,并返回新的state
├── connect.js //将redux和展示组件做关联,将redux中的属性和方法挂载到组件里
安装依赖:在终端中执行下面的命令,安装 redux 和 react-redux
yarn add redux react-redux -S
store.js文件:
/* store.js */
import {
createStore} from 'redux'
import reducer from './reducer'
//创建store
const store=createStore(reducer)
export default store;
reducer.js文件:
初始值
;数据做操作
;新的state
,当 state 被更改后,store.subscribe 方法里的回调函数就会执行,会通知 view 去重新获取 state,做视图的更新;/* reducer.js */
const defaultState={
count:1}
const reducer=(state=defaultState,action)=>{
switch (action.type){
case "inc":
return{
count:state.count+action.num }
case "dec":
return{
count:state.count-1 }
default:
return state;
}
}
export default reducer;
connect.js文件:
redux
和展示组件
做关联
,将 store 里的属性和方法挂载到组件里;connect(mapStateToProps?, mapDispatchToProps?)(component)
props
上的属性;props
上的方法;/* connect.js */
import {
connect} from 'react-redux'
const mapState=(state)=>{
return{
count:state.count }
}
const mapDispatch=(dispatch)=>{
return{
increm:(data)=>{
dispatch({
type:"inc",num:2}) },
decrem:()=>{
dispatch({
type:"dec"}) }
}
}
export default connect(mapState,mapDispatch)
Count.jsx :
/* Count.jsx */
import React, {
Component } from 'react'
import Button from './Button'
import connect from './connect'
class Count extends Component {
render() {
return (
<div>
<Button type="inc">+</Button>
<span>{
this.props.count}</span>
<Button type="dec">-</Button>
</div>
)
}
}
export default connect(Count)
Button.jsx:
/* Button.jsx */
import React, {
Component } from 'react'
import connect from './connect'
class Button extends Component {
clickHandle=()=>{
let {
type,increm,decrem} =this.props;
if(type==="inc") increm(2)
else decrem()
}
render() {
return (
<button onClick={
this.clickHandle}>
{
this.props.children}
</button>
)
}
}
export default connect(Button)
index.js:
,并提供 store
属性,则在后代组件中都可以通过 connect 对组件做增强,读到 store 里的属性和方法;/* index.js */
import React from 'react'
import ReactDOM from 'react-dom';
import {
Provider} from 'react-redux'
import store from './store'
import Count from './Count'
ReactDOM.render(
<Provider store={
store}>
<Count/>
</Provider>,
document.getElementById('root')
);
总结:
react-redux 中两个核心的api:
react-redux 开发思想:
Redux 的 React 绑定库是基于容器组件和展示组件相分离的开发思想。
展示组件 | 容器组件 | |
---|---|---|
作用 | 描述如何展现(骨架、样式) | 描述如何运行(数据获取、状态更新) |
直接使用 Redux | 否 | 是 |
数据来源 | props | 监听 Redux state |
数据修改 | 从 props 调用回调函数 | 向 Redux 派发 actions |
调用方式 | 手动 | 通常由 React Redux 生成 |
大部分的组件都应该是展示型
的,但一般需要少数的几个容器组件把它们和 Redux store 连接起来。技术上讲你可以直接使用 store.subscribe() 来编写容器组件
。但不建议这么做的原因是无法使用 React Redux 带来的性能优化。也因此,不要手写容器组件,而使用 React Redux 的 connect()
方法来生成。