# 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