改造 Count 组件把 action 复制到该文件中
const increment = { type: 'increment' } const decrement = { type: 'decrement' } function Count({count,dispatch}) { return <div> <button onClick={() => {dispatch(increment)}}>+</button> <span>{count}</span> <button onClick={() => {dispatch(decrement)}}>-</button> </div> }现在项目已经可以运行了但是Count组件中的 提交Action的那一长串代码影响视图的可读性,所以代码还是需要优化
计数器案例代码优化-让视图中的代码可读性更高我们希望视图中直接调用一个函数这样视图代码可读性强,这个需要利用connect的第二个参数,第二个参数是一个函数,这个函数的形参就是dispatch方法,要求这个函数返回一个对象,返回的这个对象中的内容都会映射到组件的props属性上
申明一个变量为connect中的第二个参数,在这个变量中返回执行不同action操作的对象
// connect 的第二个参数 这个参数是个函数 这个函数的形参就是dispatch方法 要求返回一个对象 这个对象中的属性会被映射到组件的props上 const mapDispatchToProps = dispatch => ({ increment (){ dispatch({ type: 'increment' }) }, decrement (){ dispatch({ type: 'decrement' }) } }) // connect 的参数为一个函数 这个函数可以拿到store中的状态,要求我们这个函数必须返回一个对象,在这个对象中写的内容都会映射给组件的props属性 // connect 调用后返回一个函数 返回的这个函数继续调用需要传入组件告诉connect需要映射到那个组件的props export default connect(mapStateProps, mapDispatchToProps)(Count)在组件中结构props在视图中直接绑定事件
function Count({count,increment,decrement}) { return <div> <button onClick={increment}>+</button> <span>{count}</span> <button onClick={decrement}>-</button> </div> }通过这次优化我们发现 调用 dispatch 触发action 的方法的代码都是重复的,所以还需要继续优化
优化调用 dispatch 触发action 的方法的重复代码简化利用 bindActionCreators 来简化 dispatch 触发 action的操作,bindActionCreators来帮助我们生成执行action动作的函数
bindActionCreators 有两个参数,第一个参数为 执行action的对象,第二个参数为 dispatch方法
分离action操作,新建store/actions/counter.actions.js文件把执行action操作单独放在这个文件并导出
export const increment = () => ({type: 'increment'}) export const decrement = () => ({type: 'decrement'})在Count.js中导入关于计数器的action,用bindActionCreators方法来生成dispatch执行action函数
import { bindActionCreators } from 'redux' import * as counterActions from './../store/actions/counter.actions' const mapDispatchToProps = dispatch => (bindActionCreators(counterActions, dispatch)) // connect 的参数为一个函数 这个函数可以拿到store中的状态,要求我们这个函数必须返回一个对象,在这个对象中写的内容都会映射给组件的props属性 // connect 调用后返回一个函数 返回的这个函数继续调用需要传入组件告诉connect需要映射到那个组件的props export default connect(mapStateProps, mapDispatchToProps)(Count)代码优化到这里我们发现,redux的代码与组件融合在一起,所以我需要拆分成独立的,为什么要抽离redux呢?因为我们要让我们的代码结构更加合理
重构计数器,把redux相关代码抽离把reducer函数抽离为单独的文件、把创建store抽离到单独的文件中
因为在reducer 和 actions中我们都写了字符串,但是字符串没有提示所以我们把字符串定义成常量防止我们出现单词错误这种低级错误,新建 src/store/const/counter.const.js 文件
export const INCREMENT = 'increment' export const DECREMENT = 'decrement'新建 src/store/reducers/counter.reducers.js 文件把 reducer 函数抽离到此文件中
import { INCREMENT, DECREMENT} from './../const/counter.const' const initialState = { count: 0 } // eslint-disable-next-line import/no-anonymous-default-export export default (state = initialState, action) => { switch (action.type) { case INCREMENT: return { count: state.count + 1 } case DECREMENT: return { count: state.count - 1 } default: return state } }更改actions中的字符串为引入变量
import { INCREMENT, DECREMENT} from './../const/counter.const' export const increment = () => ({type: INCREMENT}) export const decrement = () => ({type: DECREMENT})