react-redux
react-redux需要配合 redux使用,react-redux可实现 redux与react的连接
但需遵循如下规范:
1.所有UI组件都应该包裹一个容器组件,他们是父子关系
2.容器组件是真正和redux打交道的,里面可以随意使用redux的api
3.UI组件中不能使用任何redux api
4.容器组件会传给UI组件:1.redux中保存的状态,2.用于操作状态的方法
5.备注:容器给UI传递:状态、操作状态的方法,均通过props传递
基本使用
1.确保ui组件已经创建
2.创建ui组件的容器组件,用于将ui组件与redux进行连接
在容器组件键入
代码语言:javascript复制/container/Count.jsx
// 引入 ui 组件
import CountUI from '../../components/Count'
// 引入connect用于连接ui组件与redux
import { connect } from 'react-redux'
export default connect()(CountUI)
3.将使用UI组件的地方替换为容器组件 如在App.jsx
代码语言:javascript复制//App.jsx
import React, { Component } from 'react'
import Count from './container/Count'
import store from './redux/store'
export default class App extends Component {
render() {
return (
<div>
// 给容器组件传入store 将ui组件与redux连接起来
<Count store={store}>
</div>
)
}
}
注意这里需要将store通过props的方式传给容器组件,而不是在容器组件里面直接引用
容器组件如何给ui组件传递状态?
需要给connect函数传递两个参数 第一个参数是给ui组件的状态,第二个参数是给ui组件的操作状态的方法 但这两个参数必须是函数,通过函数的返回值给到ui组件 如下
代码语言:javascript复制// 引入 ui 组件
import CountUI from '../../components/Count'
// 引入connect用于连接ui组件与redux
import { connect } from 'react-redux'
// 该函数返回的对象中的key,就是传递给ui组件的props的key
function mapStateToProps(state) {
// state相当于 store.getState()
return { n:state }
// ui组件访问 this.props.n
}
function mapDispatchToProps(dispatch) {
// dispatch 相当于 store.dispatch
return {
jia:(data)=>{
// 通知redux执行状态改变
dispatch({type:'add', data:data})
// UI组件直接 通过 this.props.jia(data) 执行
}
...
}
}
export default connect(mapStateToProps,mapDispatchToProps)(CountUI)
上面的代码有点麻烦,接下来进行优化 如果使用了规范的redux可以改为下面的形式
代码语言:javascript复制export default connect(
mapStateToProps,
{
jia:createIncrementAction, // action 需新建文件定义
jian:createDecrementAction
...
}
)(CountUI)
// count_action.js
export const createIncrementAction = data => {type:'incremnt', data};
可以看到 第二个参数我们直接传了一个对象,react-redux会帮我们处理
在ui组件访问 this.props.jia this.props.jian
Provider组件使用
如果容器组件很多,那就需要传很多次store给容器组件,这里可以通过Provider解决 在index.js入口文件
代码语言:javascript复制...
import { Provider } from 'react-redux'
import store from '../../store'
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
)
注册多个reducer
reducer用来操作本地数据 如下两个reducer
代码语言:javascript复制// redux/reducers/person.js
const initState = [
{ id:001,name:'tome',age:18 }
]
export default function personReducer (preState=initState,action) {
const { type,data } = action
switch(type) {
case 'addPerson':
return [data,...preState]
default:
return preState
}
}
// redux/reducers/count.js
const initState = 0
export defualt function countReducer(preState=initState,action ) {
const { type, data } = action
switch(type) {
case 'increment':
return preState data
default:
return preState
}
}
在 store.js注册多个reducer
代码语言:javascript复制// /redux/store.js
// combineReducers 用于注册多个reducer
import { createStore,applyMiddleware,combineReducers } from 'redux'
import countReducer from './reducers/count'
import personReducer from './reducers/person'
// 引入 redux-thunk 用于支持异步的action
import thunk from 'redux-thunk'
const allReducers = combineReducers({
he:countReducer,
ren:personReducer
})
// 经过 combineReducers state变成了一个对象
// 任何容器组件都可以访问的state里面的值,实现数据共享
// 在容器组件要注意改变 取state.里面的值
//暴露store
export default createStore(allReducer,applyMiddleware(thunk))
注意 redux中的reducer函数必须是一个纯函数
也就是必须遵循 1.不得改写参数数据 2.不会产生任何副作用如网络请求 3.不能调用 Data.now()或者Math.random()等不纯方法
所以reducer不能使用 一些数组方法如 unshift,push直接对原参数进行修改 不是纯函数会影响redux对状态的改变 这样会造成数据不响应,不会更新到视图