React 状态管理 - Redux 入门

目录

扩展学习资料

Redux基础

Redux动机

Redux核心概念

Redux的三个原则

Redux运转图

React & Redux的搭配使用

Redux API

React-Redux API(关联组件)

从头创建一个工程

@package.json

 @/src/reducer/index.js

@/src/reducer/home/index.js

@/src/actions/home/index.js

@/src/actions/mutation-types.js

@/src/store/index.js

@/src/index.jsx

@/src/routes/index.js

@/src/view/index.html

@/src/app.jsx

@/src/containers/home/index.jsx

小结


扩展学习资料

名称

链接

Redux 文档

Redux 中文文档 · Redux

Redux 插件

redux middleware 详解 - 知乎

构建复杂React应用

Redux基础

Redux动机

为什么需要Redux?

  • Redux适合于大型复杂的单页面应用。

单页面应用;需要管理的状态;多且复杂;页面之间共享状态

 

Redux核心概念

state : 应用全局数据的来源,数据驱动视图的核心

action: 数据发生改变动作的描述

reducer : 结合state和action,并返回一个新的state

Redux的三个原则

三大原则

  • 单一数据源 整个应用的state被储存在一棵object tree中,并且这个object tree 只存在于唯一一个store中。
  • State 是只读的 唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象。
  • 使用纯函数来执行修改State 可纯函数意味着同样的输入就会有同样的输出。

Redux运转图

全局状态Store操控->视图View变更触发->Actions->Reducers接收->返回给Store不同的小state构成全局状态Store

 

React & Redux的搭配使用

Redux API

  • createStore 创建一个Reudx store 来存放应用中所有的state。
  • combineReducers 将多个不同reducer函数作为value的object,合并成一个最终的reducer函数。
  • applyMiddleware 接受自定义功能的middleware来扩展Redux。
  • compose 函数式编程中的方法,右到左来组合执行参数。

React-Redux API(关联组件)

  • connect 将React组件与Redux链接起来。
  • Provider 提供被connect链接起来的组件能够访问得到Store。

从头创建一个工程

@package.json
// yarn
// 报错,清一下缓存:yarn cache clean 
{
  "name": "redux-reselect",
  "version": "1.0.0",
  "description": "reselect",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --hot --color --progress --host localhost --config webpack.config.js --env.dev",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/luzuoquan/redux-reselect.git"
  },
  "keywords": [
    "reselect",
    "redux"
  ],
  "author": "luzuoquan",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/luzuoquan/redux-reselect/issues"
  },
  "homepage": "https://github.com/luzuoquan/redux-reselect#readme",
  "devDependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.9.6",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-decorators": "^7.8.3",
    "@babel/plugin-proposal-export-default-from": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.9.6",
    "@babel/preset-env": "^7.9.6",
    "@babel/preset-react": "^7.9.4",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^8.1.0",
    "eslint": "6.8.0",
    "eslint-config-airbnb": "^18.1.0",
    "eslint-import-resolver-webpack": "^0.12.1",
    "eslint-plugin-import": "^2.20.2",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.19.0",
    "eslint-plugin-react-hooks": "3.0.0",
    "html-webpack-plugin": "^4.3.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "@babel/runtime": "^7.9.6",
    "core-js": "^3.6.5",
    "immer": "^7.0.1",
    "prop-types": "^15.7.2",
    //react
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    // router
    "react-router": "^5.1.2",
    "react-router-dom": "^5.1.2",
    // redux
    "react-redux": "^7.2.0",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0",
    
    "regenerator-runtime": "^0.13.5",
    "reselect": "^4.0.0",
    "whatwg-fetch": "^3.0.0"
  }
}
 @/src/reducer/index.js
import { combineReducers } from 'redux';
import homeReducer from './home';

// console.log(reSelectReducer());
// 合并多个reducer
// 扩展性
export default combineReducers({
  homeReducer,
  //...
});
@/src/reducer/home/index.js
import * as types from '@/actions/mutation-types';
// 初始值
const initialState = {
  homeName: '云',
};
// 操作
const mutations = {
  // 获取
  [types.QUERY_GLOBAL_NAME](state) {
    return { ...state }; // 解构
  },
  // 更新
  [types.UPDATE_GLOBAL_NAME](state, action) {
    return {
      ...state,
      homeName: action.payload,
    };
  },
};
export default function (state = initialState, action) {
  // 如果当前动作不存在,返回初始值
  if (!mutations[action.type]) return state;
  // 执行对应方法
  return mutations[action.type](state, action);
}
@/src/actions/home/index.js
import * as types from '../mutation-types';
// 请求数据方法
export function queryName(params) {
  return {
    type: types.QUERY_GLOBAL_NAME,
    payload: params,
  };
}
// 改变数据方法
export function updateName(params) {
  return {
    type: types.UPDATE_GLOBAL_NAME,
    payload: params,
  };
}
// 异步请求数据
export function queryAsyncName(params) {
  return (dispatch) => {
    setTimeout(() => {
      dispatch({
        type: types.QUERY_GLOBAL_NAME,
        payload: params,
      });
    }, 2000);
  };
}
// 异步修改数据
export function asynUpdatecName(params) {
  return async (dispatch) => {
    setTimeout(() => {
      dispatch(updateName(params));
    }, 3000);
  };
}
@/src/actions/mutation-types.js
// 所有动作枚举文件
// 查询
export const QUERY_GLOBAL_NAME = 'QUERY_GLOBAL_NAME';
// 更新
export const UPDATE_GLOBAL_NAME = 'UPDATE_GLOBAL_NAME';

export const FILTER_ALL_DATA = 'FILTER_ALL_DATA';
export const FILTER_SUCCESS_STATUS = 'FILTER_SUCCESS_STATUS';
export const FILTER_FAIL_STATUS = 'FILTER_FAIL_STATUS';
export const UPDATE_FILTER_STATUS = 'UPDATE_FILTER_STATUS';
export const UPDATE_IMMUTABLE_DATA = 'UPDATE_IMMUTABLE_DATA';
export const UPDATE_REDUX_ACTIONS_DATA = 'UPDATE_REDUX_ACTIONS_DATA';
@/src/store/index.js
import { createStore } from 'redux';

import reducers from '@/reducer';

export default createStore(
  reducers
);
@/src/index.jsx
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './app';
render(
    // Provider提供被connect链接起来的组件能够访问得到Store。
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#app'),
);
@/src/routes/index.js
import React from 'react';
import {
  BrowserRouter,
  Route,
} from 'react-router-dom';
import Home from '@/containers/home';

export default function () {
  return (
    <BrowserRouter>
      <Route exact path="/" component={Home} />
    </BrowserRouter>
  );
}
@/src/view/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>React Redux Demo</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>
@/src/app.jsx
import React from 'react';
import Routes from '@/routes';
export default () => <Routes />;
@/src/containers/home/index.jsx
/* eslint-disable react/no-unused-prop-types */
import React, { Component } from 'react';

import {
  updateName,
  queryAsyncName
} from '@/actions/home';
import { connect } from 'react-redux';
// react-redux API connect将组件与react链接起来
// connect与home页面关联起来,装饰器写法
@connect(
  (state) => state.homeReducer,
  (dispatch) => ({
    updateName: (params) => dispatch(updateName(params)),
  }),
)
export default class Home extends Component {
  handleClick = () => {
    const {
      updateName,
    } = this.props;
    updateName('修改云课堂');
  }
  render() {
    const { homeName } = this.props;
    return (
      <div>
        <div>
          {homeName}
        </div>
        <button
          type="button"
          onClick={this.handleClick}
        >
          更改
        </button>
      </div>
    );
  }
}

小结

Redux基础:核心原则【改变数据的方式只能事action】

React-Redux :只做一个单页面应用的流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值