# counter **Repository Path**: bigMuMu/counter ## Basic Information - **Project Name**: counter - **Description**: 基于redux实现的简单的计数器(学习) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-09-27 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 计数器(redux) 最近在看着官方的示例 TODOList 学习 redux ,决定自己实现一个基于react、redux的计数器 ## actions Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。**它是 store 数据的唯一来源。** 一般来说你会通过 store.dispatch() 将 action 传到 store。要想更新 state 中的数据,你需要发起一个 action。记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。官方规定 action 内必须使用一个字符串类型的 **type** 字段来表示将要执行的动作。 actions 就是 **简单的对象** ,比如 ```js // src/actions/index.js export const increase = { type: 'INCREASE', } ``` ## Action 创建函数 Action 创建函数 就是生成 action 的方法。“action” 和 “action 创建函数” 这两个概念很容易混在一起,使用时最好注意区分。 在 Redux 中的 action 创建函数只是简单的返回一个 action(返回的还是简单的对象): ```js // 官方示例 function addTodo(text) { return { type: ADD_TODO, text } } ``` ## 实现计数器 计数器就是加加减减,所以先创建 actions(要执行什么动作),计数器的动作就是 **加** 或者 **减** ,这里我们创建两个 action ,increase(增加)和 reduce(减少) ```js export const increase = { type: 'INCREASE', } export const reduce = { type: 'REDUCE', } ``` ## reducers 怎么样通过 action 这个动作去执行相应的操作并且更改 state 呢,这就需要 reducer 。Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的。 ```js // src/reducers/index.js const stores = (state = {count: 0}, action) => { switch (action.type) { case 'INCREASE' : return {count: state.count + 1} case 'REDUCE' : return {count: state.count - 1} default: return state } } ``` 接下来就是页面显示部分了,一般目录里面用 **Container** 表示容器组件,用 **Component** 表示展示组件, - 容器组件位于应用最顶层的组件,用来与redux连接的。从redux中获取数据作为props。 - 展示组件位于应用的中间或者子组件,是纯粹的组件,与redux没有关系。他们从自己的父组件获取数据作为props,他们的共同根组件是应用的唯一的容器组件。 区分容器组件和展示组件的好处: - 展示和容器更好的分离,更好的理解应用程序和UI - 重用性高,展示组件可以用于多个不同的state数据源 - 展示组件就是你的调色板,可以把他们放到单独的页面,在不影响应用程序的情况下,调整UI - 迫使你分离标签,达到更高的可用性 ```js const mapStateToProps = (state) => { return { count: state.count } } const mapDispatchToProps = (dispatch) => { return { increaseClick: () => { dispatch(increase) }, reduceClick: () => { dispatch(reduce) } } } // connect的意思就是连接展示组件与容器组件 const AddCount = connect( mapStateToProps, mapDispatchToProps )(Counter) ``` ## connect connect方法接受两个参数:mapStateToProps和mapDispatchToProps。前者负责输入逻辑,即将state映射到 UI 组件的参数(props),后者负责输出逻辑,即将用户对 UI 组件的操作映射成 Action。 ## mapStateToProps **mapStateToProps** 是一个函数,有2个参数,第一个参数就是 **Redux** 的 **state** ,第二个参数 **ownProps** ,是组件(容器组件的props对象)自己的 props。有的时候,ownProps 也会对其产生影响。该函数返回一个对象,这个对象有一个 count 属性,代表 UI 组件的同名参数。 **mapStateToProps** 会订阅 Store,每当 state 更新的时候,就会自动执行,重新计算 UI 组件的参数,从而触发 UI 组件的重新渲染。使用ownProps作为参数后,如果容器组件的参数发生变化,也会引发 UI 组件重新渲染。 ## mapDispatchToProps mapDispatchToProps是connect函数的第二个参数,用来建立 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操作应该当作 Action,传给 Store。 最后就是创建 store ```js let store = createStore(alterCount) ReactDOM.render( , document.getElementById('root')); ```