草珊瑚的redux使用方式
前言
阮大师写入门教程能力一流。
首推它的Redux三篇入门文章。
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_three_react-redux.html
这三篇文章介绍了,
Redux的基本概念和API,异步操作,以及如何跟React相结合。
文章写得不错,但实践起来还是略显繁琐。
思考
下面提出我自己对Redux结合React使用的思考。
使用ramda库组合自定义中间件。
这使得代码更灵活和透明。异步操作也结合ramda库。
可以不用引入第三方redux-thunk
,redux-promise
中间件。
使用ramda库更方便组合异步操作。state以React组件的state为准。
redux的state只是辅助计算出React组件的state。往store注入trigger函数,用来setState更新React组件。
在线demo
示例代码如下:
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<h1>Hello world</h1>
<div id="app"></div>
<script src="index.js"></script>
</body>
</html>
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import store from './store.js';
import {connect} from './connect.js';
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
value:0,
otherNum:0,
asyncing:false
};
}
dispatch(obj){
obj.state= this.state;
store.dispatch(obj);
}
setOtherData(){
this.dispatch({ type: 'Other' });
}
setData(){
this.dispatch({ type: 'INCREMENT' });
}
async(){
this.dispatch({type: 'Loading' });
this.dispatch({ type: 'ASYNC'});
}
componentDidMount(){
//store.dispatch({type: 'Init'})
}
render() {
const t = this;
console.log('render', store.getState(), t.state);
const {value ,asyncing,otherNum } = t.state;
return (
<div>
<div>数字:{value}</div>
<div onClick={t.setData.bind(this)}>点我+1</div>
{
(()=>{
if(asyncing){
return (<div>异步加载中</div>);
}
else{
return (<div onClick={t.async.bind(t)}>点我异步+10</div>);
}
})()
}
<br />
<div onClick={t.setOtherData.bind(this)}>点我其他数字+1</div>
<div>其他数字:{otherNum}</div>
</div>);
}
}
const NewTest = connect(store)(Test) ;
ReactDOM.render(
<NewTest />,
document.getElementById('app')
)
module.exports = NewTest;
store.js
import { createStore } from 'redux';
import R from 'ramda';
const isPromise = function(e){
return !!e&&typeof e.then=="function";
};
const setTimeout1 = R.curry(function( state ){
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve(state+ 10);
},1000);
})
});
// reducer,仅用于计算。
function counter(state = {}, action) {
if(isPromise(state)){
state = {};
}
state = R.merge(state, action.state);
console.log('reducer中的state',state);
switch (action.type) {
case 'Init':
return action.state;
case 'INCREMENT':
state.value = state.value + 1;
return state
case 'ASYNC':
return R.composeP( setTimeout1)(state.value);
case 'Loading':
return {asyncing: true}
case 'Other':
return {otherNum: state.otherNum+1};
default:
return state
}
}
let store = createStore(counter);
// subscribe,可用于执行含有副作用的操作。
store.subscribe((e) =>{
console.log('subscribe',store, store.getState(),e, this);
let state = store.getState();
if(isPromise(state)){
state.then(function(num){
store.trigger({value: num, asyncing:false });
})
}
else{
store.trigger(store.getState());
}
})
module.exports = store;
connect.js
import {type} from 'ramda';
exports.connect = function (listenable, context) {
if(type(listenable) !== 'Object'){
throw new Error('connect function\'s argument is not a object');
}
listenable.trigger = function (obj,fn) {
this.setState(obj || {}, fn);
};
listenable.getReactState = function(){
return this.state;
};
return function(otherReactClass){
return class baseReactClass extends otherReactClass {
constructor(){
super();
}
componentDidMount(...args) {
context = context || this;
listenable.trigger = listenable.trigger.bind(context);
listenable.getReactState = listenable.getReactState.bind(context);
super.componentDidMount();
}
componentWillUnmount() {
listenable.trigger = null;
super.componentWillUnmount();
}
}
}
}
草珊瑚的redux使用方式的更多相关文章
- 翻译 | Thingking in Redux(如果你只了解MVC)
作者:珂珂(沪江前端开发工程师) 本文原创,转载请注明作者及出处. 原文地址:https://hackernoon.com/thinking-in-redux-when-all-youve-known ...
- redux 与 react-redux
Redux 一.Redux 三大原则: 1.一个应用永远只有一个数据源(整个应用状态都保存在一个对象中,Redux提供的工具函数combineReducers可以解决庞大的数据对象的问题) 2.状态是 ...
- 我所遭遇过的游戏中间件---Redux
我所遭遇过的游戏中间件---Redux 一.关于Redux Substance Redux 是一款纹理处理软件加中间件,专门用于纹理生成和压缩.具其用户指南介绍,它能够对纹理集进行优化,可以将现有压缩 ...
- redux详解
redux介绍 学习文档:英文文档,中文文档,Github redux是什么 redux是一个独立专门用于做状态管理的JS库(不是react插件库),它可以用在react, angular, vue等 ...
- 前端AntD框架的upload组件上传图片时遇到的一些坑
前言 本次做后台管理系统,采用的是 AntD 框架.涉及到图片的上传,用的是AntD的 upload 组件. 前端做文件上传这个功能,是很有技术难度的.既然框架给我们提供好了,那就直接用呗.结果用的时 ...
- React+DvaJS 之 hook 路由权限控制
博客 学院 下载 GitChat TinyMind 论坛 APP 问答 商城 VIP 活动 招聘 ITeye 写博客 发Chat 登录注册 原 React+DvaJS 之 hook 路由权限控制 20 ...
- react的状态管理
近两年前端技术的发展如火如荼,大量的前端项目都在使用或转向 Vue 和 React 的阵营, 由前端渲染页面的单页应用占比也越来越高,这就代表前端工作的复杂度也在直线上升,前端页面上展示的信息越来越多 ...
- react之传递数据的几种方式props传值、路由传值、状态提升、redux、context
react之传递数据的几种方式 1.父子传值 父传值:<子的标签 value={'aaa'} index={'bbb'}></子的标签> 子接值:<li key={thi ...
- 使用redux代码文件的组织方式
从架构触发,开始一个新应用的时候,代码文件的组织方式一定要考虑好 如果之前使用过mvc的框架那么对按角色组织方式一定不陌生 角色组织方式 reducer/ todoReducer.js filterR ...
随机推荐
- vim编辑文件警告Swap file already exists ,如何删除vim编辑产生的.swp文件?查看隐藏文件命令
vim编辑文件警告Swap file already exists,如何删除vim编辑产生的.swp文件?查看隐藏文件命令 Linux(centos7)下多个用户同时编辑一个文件,或编辑时非正常关闭, ...
- strace跟踪多进程与内核的交互
1.ptrace的说明 ptrace原型: #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_t ...
- [转载]oracle的常用函数 instr() 和substr()函数
在Oracle中 可以使用instr函数对某个字符串进行判断,判断其是否含有指定的字符. 在一个字符串中查找指定的字符,返回被查找到的指定的字符的位置. 语法: instr(sourceString, ...
- [转载]window.location.href的用法(动态输出跳转)
无论在静态页面还是动态输出页面中window.location.href都是不错的用了跳转的实现方案 javascript中的location.href有很多种用法,主要如下. self.loca ...
- flask框架----flask中的wtforms使用
一.简单介绍flask中的wtforms WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证. 安装: pip3 install wtforms 二.简单使用wtfo ...
- 前端框架VUE----导入Bootstrap以及jQuery的两种方式
Vue引入bootstrap主要有两种方法 方法一:在main.js中引入,此方法导入的bootstrap中对于html,body的一些预设置的css样式可能无效. 一.引入jQuery 在当前项目的 ...
- Centos7 安装 apache + php7.0 环境
安装apache rpm -qa|grep httpd 查看是否安装 yum install httpd 安装 service httpd start 启动服务 测试是否 启动 I ...
- css 初级进阶
摘自:https://www.jianshu.com/p/dcc40ccc9841 CSS中级 Class和ID选择器 CSS初级教程中我们可以使用HTML标签选择器定义样式. 同样你也可以使用Cla ...
- struts2 的入门案例
下面写一个struts2 的一个小例子 首先需要struts2 的jar 可以在Struts 官网上下载 本人使用的版本是2.5 17 官网地址: http://struts.apache ...
- make是如何工作的
在默认的方式下,也就是我们只输入make命令.那么,1.make会在当前目录下找名字叫“Makefile”或“makefile”的文件.2.如果找到,它会找文件中的第一个目标文件(target),在上 ...