再学 Redux

redux核心概念

  1. components View react页面
  2. Action 如果需要修改store的数据必须派发一个动作,它的参数接收一个对象,对象里面必须要有一个type属性,表示动作的类型,第二个属性是你传入的值
  3. Reducer 它必须是一个纯函数,来处理store数据的变化,它接收两个参数 一个是state 上一次的数据, 一个是action . 特别注意的是 不能在这里面修改 state数据或者action数据
  4. Store 仓库 存放state数据 它是链接action与reducer的桥梁 它的实例对象上有些方法,需要去记住它.
  • getState() 获取当前仓库的 state 数据

  • dispacth(action) 派发一个动作

  • subscribe(cb) 监听仓库数据的变化,如果仓库数据有变化,这个回调函数就会执行

  • unsubscribe(cb) 取消监听 当仓库的数据发生改变的时候 subscribe里面的回调函数会触发,重新返回一个函数 这个函数需要在 componentswillunmount() {}这个生命周期钩子函数里面执行,执行之后就当组件销毁的时候,componentswillunmount()生命周期钩子函数会执行里面的 回调函数也会执行就取消订阅了.

  1. ActionTypes
    动作类型常量
  • 如果动作类型是一个字符串的话.出现bug 会非常恶心.
  • 作用只是解决字符串写错之后,调试bug 非常困难的问题
  1. ActionsCreates
  • 动作生成器
  • 就是一个函数这个函数调用之后,返回一个动作的对象

7.安装 redux

npm install -- save redux || yarn add redux

拆分主reducer, 每个模块的状态都在reducer里面,将每个模块的状态拆分出去,在主的reducer文件中进行引用, 这时就要使用 redux里面的combineReducers方法,这个方法

在 主reducer.js文件中 调用redux的combineReducers方法,返回一个reducer纯函数 并且把它暴露出去

8. redux的中间件

可以阮一峰学习文档参考链接
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html
中间件主要的作用就是帮助我们实现异步代码
之前动作一旦被派发,是直接到了 reducer 的纯函数里面,加上中间件之后,动作派发之后,首先会经过中间件来处理,处理之后再到reducer里面去

中间件实现的原理
就是对 store,dispacth 进行重写
代码如下:

var  next = store.dispacth()
对store 进行重写
store.dispacth= (action)=>{
默认接收一个 action 对象
console.log("操作之前的数据",store.getState());
next(action);
console.log("操作之后的数据",store.getState())
}

  1. 使用第三方提供的redux-logger 中间件
    作用主要是在 控制台 日志输出的中间件
  • 安装 yarn add redux-logger --save 或 npm i --save redux-logger
    在主仓库中引入:
  • import logger from 'redux-logger'
    在主仓库的createStore(),传递 redux 的 applyMiddleware 调用即可
    applyMiddleware 主要作用就是使用中间件,这个函数用中间件作为参数比如: logger thunk saga 一般的话, logger需要放在后面
    代码如下:
import { createStore, applyMiddleware, compose } from "redux";

import reducer from "./reducer";
import logger from "redux-logger";

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(logger)));

export default store;
  1. 使用第三方提供的redux-thunk中间件(让Redux能够实现异步的代码)
  • 安装 yarn add redux-thunk --save
  • 默认store.dispacth()只能接受一个对象,如果使用了redux-thunk这个中间件 store.dispacth()能接受一个函数
  • 简单demo如下写在组件里面
派发一个异步动作
store.dispatch(() => {
这里写一个异步的代码
      var url = "http://localhost:9090/shuju";
      fetch(url)
        .then(response => response.json())
        .then(res => {
再派发一个普通的动作
          store.dispatch(initlist(res));
        });
    });
  • 需要将这个方法放在 actionCreate.js 里面
    因为在组件页面中 使用 store.dispacth() 这个方法使用了thunk 之后,里面可以接受一个函数或者是对象,在这个store.dispacth()参数的函数 放到actionCreate.js 里面自定义各一个函数里面可以发起ajax网络请求 actionCreate里面的函数经过第三方中间件的处理主动接受的参数有 store里面的 dispacth,getState 这两个方法,这样就不需要在重新的引入 store了 可以直接在 dispacth()一个动作给reducer.js
    第一种方式组件里面的代码:
直接派发一个动作,但是这个动作是在actionCreate里面写
    使用方式1 store.dispatch(initTodoSync); 注意不能加括号 , thunk 会让initTodoSync执行
(加括号的话initTodoSync返回一个undefined 而 store.dispacth 不能接受一个undefined)

第一种方式actionCreate代码如下:

export const initlist = list => {
  return {
    type: INIT_LIST,  // 主的reducer文件中根据这个动作的类型,把获取到的数据给store
    list
  };
};
export const initTodoSync = (dispatch, getState) => {
  var url = "http://localhost:9090/shuju";
  fetch(url)
    .then(response => response.json())
    .then(res => {
      console.log(res, "获取成功了吗?");
      console.log(getState());
      dispatch(initlist(res)); // 调用重新初始化仓库数据的函数,把获取的数据传过去
    });
};

第二种方式组件里面的代码:

store.dispatch(initTodoSync());  //加括号

第二种方式actionCreate代码如下:

export const initlist = list => {
  return {
    type: INIT_LIST,
    list
  };
};

export const initTodoSync = () => {
  return (dispatch, getState) => {
    var url = "http://localhost:9090/shuju";
    fetch(url)
      .then(response => response.json())
      .then(res => {
        console.log(res, "获取成功了吗?");
        console.log(getState());
        dispatch(initlist(res));
      });
  };
};

redux-thunk 实现的原理:

var next = store.dispacth()
store.dispacth=(action)=>{
if(action && typeof action=== "function"){
//动作是个函数,就会直接执行这个动作,并且把两个参数传递下去
action(state.getState,state.dispacth)
} else{
  next(action)
  }
}

redux-react

安装: npm install react-redux || yarn add react-redux
UI组件与容器组件的概念
UI组件: 只是负责数据的渲染,不负责数据的操作. 不负责跟仓库打交道,所有的数据都是通过props
容器组件: 不负责数据渲染, 负责数据的操作, 跟仓库打交道 ,所有的数据都是通过仓库

connect的详解

connect 方法返回一个高阶函数,接收一个组件的参数,生成一个新的组件
connect 方法接收两个参数 第一个参数mapStateToprops (仓库数据发生改变时,自动执行,通过props属性自动给到组件页面) 第二个参数mapDispacthToProps
代码简单实现如下

import React, { Component } from "react";
import { connect } from "react-redux";

class Dashboard extends Component {
  state = {
    name: ""
  };
  render() {
    const { name } = this.props;
    return (
      <div>
        <h2>我的名字{name}</h2>
        <button onClick={onTodoClick}>修改我的名字</button>
      </div>
    );
  }
}

const mapStateToprops = state => {
  return {
    name: this.state.name
  };
};
const mapDispacthToprops = () => {
  return {
    onTodoClick: () => {
      dispatch({
        type: "SET_VISIBILITY_FILTER",
        name: this.state.name
      });
    }
  };
};
export default connect(
  mapStateToprops,
  mapDispacthToprops
)(Dashboard);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容