# react-redux
**Repository Path**: cai-lunduo/react-redux
## Basic Information
- **Project Name**: react-redux
- **Description**: 学习react-redux的记录
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-05-28
- **Last Updated**: 2021-05-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### react-redux使用
在上面直接使用redux的时候我们会发现在组件内我们用到很多对store的逻辑操作,而React的组件应该尽量是Pure Component,我们应该把处理逻辑都给抽取出去,这时候react-redux的作用就来了。
**思想**:把组件变成Pure Component,我们再通过`connect(mapStateToProps, mapDispatchToProps)(Comp)`去连接`store`,让这个组件可以拿到`store`的数据进行展示。
这个时候就产生了两种组件区别:`UI组件`与`容器组件`
容器组件在这里就是`connect`之后返回的组件,而UI组件就是只负责展示数据的组件。
#### 用法示例
```react
import React, { Component } from 'react'
import {add, request} from '../store/actions'
import {connect} from 'react-redux'
/**
* UI组件
*/
class Comp2 extends Component {
render() {
console.log('this.props =========>', this.props);
let {count, name, add, request} = this.props
return (
{count}
{name}
)
}
}
/**
* react-redux 容器组件
*/
function mapStateToProps(state) {
return {
count: state.count,
name: state.name
}
}
let mapDispatchToProps = {
add,
request
}
export default connect(mapStateToProps, mapDispatchToProps)(Comp2)
```
由于我们没有再在UI组件内使用`store.subscribe`订阅,此时数据不会更新,所以我们可以通过改变`props`让组件重新渲染,`connect`第一个参数是`mapStateToProps`,是一个函数,负责将`state`映射到`props`;`connect`第二个参数是`mapDispatchToProps`,是一个函数,负责将`dispatch`映射到`props`,这样子我们就能在UI组件内通过`props`拿到`store`的数据了,而且`connect`内部还帮我们订阅了`store`数据的变化,一但数据更新,`props`也会跟着更新,所以就会重新渲染。
**简单总结一下**:React 只负责页面渲染, 而不负责页面逻辑, 页面逻辑可以从中单独抽取出来, 变成 store,目的就是让组件尽量变成PureComponent,然后用connect让这个组件跟store联系,connect还会帮我们订阅store的变化。
#### 进一步的模块分离
由于我们的`actions`和`reducers`是多个的,且不同组件会用到F:\学习\前端作品\JS学习\react\redux-pro\01-review\src\store\actions\request.js不同的`actions`和`reducers`,所以我们可以按照`一个组件一个action | reducer`或者`一个功能一个action | reducer`,这里采用的是后者。
将`action`的抽取到不同文件很简单,只需将对应部分给抽取到对应文件,改变一下引入路径即可;而`reducer`的抽取,我们要用的时候还需要通过`combineReducers`将各个`reducer`给合并为一个`reducers`。
新建**store/reducers**文件夹:
```react
// count.js
import {ADD} from '../constants'
let defaultState = {
count: 0,
}
export default function reducers(state = defaultState, action) {
console.log("state ===> ", state)
console.log("action ===> ", action)
switch (action.type) {
case ADD:
return {
...state,
count: state.count + action.val
}
default:
return state
}
}
// request.js
import {REQUEST_BEGIN, REQUEST_SUCCESS, REQUEST_FAIL} from '../constants'
let defaultState = {
name: 'cai',
isLoading: false,
err: {errCode: 0, errMsg: undefined }
}
export default function reducers(state = defaultState, action) {
console.log("state ===> ", state)
console.log("action ===> ", action)
switch (action.type) {
case REQUEST_BEGIN:
return {
...state,
isLoading: true
}
case REQUEST_SUCCESS:
return {
...state,
data: action.data,
isLoading: false,
err: {errCode: 0, errMsg: ''}
}
case REQUEST_FAIL:
return {
...state,
err: {errCode: action.err[0], errMsg: action.err[1]},
isLoading: false
}
default:
return state
}
}
// index.js
import countReducer from './count'
import requestReducer from './request'
import {combineReducers} from 'redux'
export default combineReducers({
count: countReducer,
request: requestReducer
})
```
**这里需要注意**:由于我们将`reducers`给分离了,我们`combineReducers`的时候分别给`counrReducer`和`requestReducer`给取了个别名`count`和`request`,我们在取值的时候需要加上命名空间:
之前的`mapStateToProps`写法:
```js
function mapStateToProps(state) {
return {
count: state.count,
name: state.name
}
}
```
现在:
```js
function mapStateToProps(state) {
return {
count: state.count.count,
name: state.request.name,
}
}
```
新建**store/actions**文件夹:
```react
// count.js
import {ADD} from '../constants'
export const add = () => {
return {type: ADD, val: 2}
}
// request.js
import { REQUEST_BEGIN, REQUEST_SUCCESS, REQUEST_FAIL } from '../constants'
export const request = () => {
return dispatch => {
// 请求前, isLoading --> true
dispatch({type: REQUEST_BEGIN, isLoading: true})
fetch("http://localhost:4000/api/foodtype")
.then(res => res.json())
.then(res => {
// 请求成功
return dispatch({type: REQUEST_SUCCESS, data: res})
})
.catch(err => {
// 请求失败
return dispatch({type: REQUEST_FAIL, err: [1, err.message]})
})
}
}
```
**另外的:**
在 根组件APP中我们需要提供`store`作为`props`传入需要用到`react-redux`的组件。
**方式一**:直接传入
```react
```
**方式二**:通过Provider统一传入(推荐方式)
```react
import {Provider} from 'react-redux'
```
**gitee链接**:https://gitee.com/cai-lunduo/react-redux