前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现一个简单的redux

实现一个简单的redux

原创
作者头像
JianLiang
修改2019-07-01 11:23:28
5110
修改2019-07-01 11:23:28
举报
文章被收录于专栏:进击的全栈

刚开始接触到redux的时候, 对于redux中的概念, 只有一个store是知道的, 其他的都像是在阅读天书一样. 网上找了很多资料和文档来阅读, 也是通过多次的实践,慢慢的对于redux的概念一知半解, 想着如此就去阅读一下源码, 或许会有不一样的收获.于是就有了这篇文章

关于redux,

只需要记住它是一个状态管理器, 于react无关, 是一个独立的库 state: 表示状态 dispatch: 改变状态 reducer: 包含改变状态的数据 subscribe: 订阅state 中间件

我们来看看redux的核心是怎么改变数据的:

代码语言:txt
复制
let state = { name: 'liang' };
state.name = 'Tim';

这样是不是就实现了数据的改变了呢?!

估计这样会被读者打死o(╥﹏╥)o , 但是redux的核心就是这样的, 我们一步步展开来说。

上面的代码虽然实现了修改, 但是却没有通知到所有使用到name的地方上,我们通过发布订阅来实践一下

代码语言:txt
复制
let state = { name: 'liang' };
let listeners = [];
function subscribe(listener) {
  listeners.push(listener);
};
function changeState(name) {
  state.name = name;
  for (let i = 0; i < listeners.length; i++) {
    const listener = listeners[i];
    listener();
  }
}

/*-------我是分割线--------*/
//订阅state中的数据
subscribe(() => {
  console.log(state.name);
});

changeState('小米'); //小米 
changeState('小红'); //小红

上面的例子确实通过发布订阅实现了数据的改变时,通知到每个监听的地方,但是却有几个问题:

  • 只能改变name,不通用
  • 公共的代码应该封装起来

于是,我们尝试着将代码封装起来,形成一个可通用的代码。

代码语言:txt
复制
function createState(initState) {
  let state = initState;
  let listeners = [];
  //订阅功能
  function subscribe(listener) {
    listeners.push(listener);
  }
  //改变状态的方法同时通知所有的订阅者
  function changeState(newState) {
    state = newState;
    for(let i = 0; i < listeners.length; i++) {
      const listener = listeners[i];
      listener();
    }
  }
  //获取状态
  function getState() {
    return state;
  }
  return { getState, changeState, subscribe };
}

我们使用上面的代码来试一下效果

代码语言:txt
复制
let initState = {
  count: 1,
  person: {
    name: '小红',
    sex: '女'
  },
};
const store = createState(initState);
store.subscribe(() => {
  let state = store.getState();
  console.log(`名字:${state.person.name},性别:${state.person.sex}`);
});
store.subscribe(() => {
  let state = store.getState();
  console.log(state.count);
});
store.changeState({ ...store.getState(), count: 2 });
//名字:小红,性别:女
//2
store.changeState({ ...store.getState(), person: { name: '小明', sex: '男' } });
//名字:小明,性别:男
//2

这样我们就实现了一个简单的状态管理器了。

这时候是不是应该不要脸的鼓励自己,完成了redux的核心☺,但是这个仅仅只是个开始,我们目标当然是完成一个完整redux了,尽管不能媲美真正的redux(毕竟人家已经是老牌选手了),但是我们不能放弃造轮子的梦想。于是,我们重新来看这段代码,假设我们修改如下

代码语言:txt
复制
store.changeState({ ...store.getState(), count: 'abc' });
//名字:小明,性别:男
//abc

从结果来看,count的类型发生了改变,它可以被任意的修改,我们需要约束一下,更希望能够有计划的去改变,而上面的代码不能够支持这种能力,于是,我们扩展开来:

  • 希望有个函数可以控制值的返回,我们叫它为handle吧
  • 让store.changeState方法知道,告诉它修改state的时候,按我们的希望的修改

我们来实现handle函数,它接受一个老的state和一个包含改变state的对象,返回新的state

代码语言:txt
复制
function handle(state, action) {
  switch(action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    case 'DECREMENT':
      return { ...state, count: state.count - 1 };
    default:
      return state;
  }
}

在我们的createState函数中增加handle函数

代码语言:txt
复制
function createState(handle, initState) {
  let state = initState;
  let listeners = [];
  //订阅功能
  function subscribe(listener) {
    listeners.push(listener);
  }
  //通知
  function changeState(action) {
    //按我们期望的返回
    state = handle(state, action);
    for(let i = 0; i < listeners.length; i++) {
      const listener = listeners[i];
      listener();
    }
  }
  function getState() {
    return state;
  }
  return { getState, subscribe, changeState };
}

我们来尝试一下:

代码语言:txt
复制
let initState = { count: 0 };
const store = createState(handle, initState);
store.subscribe(() => {
  console.log(store.getState().count);
});
store.changeState({ type: 'INCREMENT' }); //1
store.changeState({ type: 'DECREMENT' }); //0
store.changeState({ count: 'abc' }); //0

从结果来看,我们已经实现了我们的功能了,state可以按照我们期望的要求进行改变了,对count直接进行改变已经是没有效果了的。

到此为止,我们已经实现一个完整的状态管理器。这也是redux的核心之一。

现在,我们来商量一下,我们把名字改一下,把changeState改成dispatch,handle改成reducer,这样是不是感觉很厉害,很高大上的样子☺!!!毕竟reudx就是这样叫的,我们当然要向它学习了。

总结

  1. 利用发布订阅模式实现通知每个监听的地方
  2. 通过handle函数实现了有计划的控制返回的数据

redux肯定远远不止这些,如果想知道更多,请留意下回分解

详情传送门 : https://github.com/reduxjs/redux/tree/master/src

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档