action是一个普通对象 里面必须有一个type字段,代表将要执行的行为,其他字段自己规划。

action只是描述了将要发生的事情并不能直接修改状态

action创建函数 尽量是一个纯函数,他返回的是action对象

middleware 接受一个next() 的dispatch函数,返回了一个dispatch函数,将返回的dispatch函数作为下一个middleware的next() 一次类推可以达到链式的调用

它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。 你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。

不管链式调用几次dispatch 最后一次调用dispatch  必须是一个action不能是其他的。来达到数据来源的起点。

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createStore ,compose,applyMiddleware} from "redux";
import App from "./components/app";
import reducers from './reducers/index'
import {addTodo} from './actions/index'
const enhancers = compose(
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
const store = createStore(reducers,enhancers);
const logger = (store)=>next=>action=>{
console.log('action',action)
let result = next(action)
console.log('state',store.getState())
return result
}
console.log(logger(store)(store.dispatch)(addTodo('abc')))
//手动实现一个middleware
function middleware(stroe,middlewares){
middlewares = middlewares.slice()
middlewares.reverse()
let dispatch = store.dispatch
middlewares.forEach(middleware => {
dispatch = middleware(stroe)(dispatch)
})
return Object.assign({},store,{dispatch})
}
console.log(middleware(store,[logger]))
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
let nextTodoId = 0;

export const addTodo = (text) => {
return {
type: "ADD",
id: nextTodoId++,
text,
};
};
export const setVisibilityFilter = (filter) => ({
type: "SET_VISIBILITY_FILTER",
filter,
});
export const toggleTodo = (id) => ({
type: "TOGGLE_TODO",
id,
});
export const VisibilityFilters = {
SHOW_ALL: "SHOW_ALL",
SHOW_COMPLETED: "SHOW_COMPLETED",
SHOW_ACTIVE: "SHOW_ACTIVE",
};

reducer函数接收二个参数,一个是旧的状态树,一个是actions对象  返回的是一个新的状态树

可以创建多个子reducer,分别负责状态树中的一部分。最后创建一个根reducers

//子reducers
const todos = (state = [], action) => {
switch (action.type) {
case "ADD":
return [
...state,
{
id: action.id,
text: action.text,
completed: false,
},
];
break;
case "TOGGLE_TODO":
return state.map((todo) =>
todo.id == action.id ? { ...todo, completed: !todo.completed } : todo
);
break;
default:
return state;
break;
}
};
export default todos
//根reducers
import React from 'react'
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
//自定义根reducers
// const todoApp = (state={},action)=>({
// todos:todos(state.todos,action),
// visibilityFilter:visibilityFilter(state.abc,action)
// })
export default combineReducers({todos,visibilityFilter}) //combineReducers 将reducers 拆分成多个子reducers 并执行

最后通过createStore 将状态树传递到页面组件树当中

import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createStore ,compose} from "redux";
import App from "./components/app";
import reducers from './reducers/index'
const enhancers = compose(
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
const store = createStore(reducers,enhancers);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root") )

将redux应用到组件中时分为容器组件和展示组件,容器组件需要将展示组件连接到store上

//容器组件
import React from 'react'
import { connect } from 'react-redux'
import TodoList from '../components/TodoList'
import {toggleTodo,VisibilityFilters} from '../actions/index' const getVisibleTodos = (todos,filter)=>{
switch (filter) {
case 'SHOW_ALL':
return todos
break;
case 'SHOW_COMPLETED':
return todos.filter((todo)=>todo.completed)
break;
case 'SHOW_ACTIVE':
return todos.filter(t=>!t.completed)
break;
default:
throw new Error('Unknown filter: ' + filter)
}
} const mapStateToProps = (state, ownProps) => {
console.log(state)
return {
todos: getVisibleTodos(state.todos,state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
toggleTodo: (id) => {
dispatch(toggleTodo(id))
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList)
//展示组件
import React from 'react'
import Todo from './Todo'
const TodoList = ({todos,toggleTodo})=>{
return (
<ul>
{todos.map(todo=>
<Todo change={()=>toggleTodo(todo.id)} key={todo.id} {...todo} />
)}
</ul>
)
}
export default TodoList

redux初探的更多相关文章

  1. Redux初探与异步数据流

    基本认知 先贴一张redux的基本结构图 原图来自<UNIDIRECTIONAL USER INTERFACE ARCHITECTURES> 在这张图中,我们可以很清晰的看到,view中产 ...

  2. redux有价值的文档

    使用 Redux 管理状态,第 1 部分 https://www.ibm.com/developerworks/cn/web/wa-manage-state-with-redux-p1-david-g ...

  3. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

  4. 初探Parcel

    昨天趁有点时间看了前不久很火的构建工具Parcel,这里说下初步使用的感受,尤其是将其放到实际项目中和Webpack进行比较. 一.前言 首先说下笔者目前的技术栈.最近的前端项目主要以管理后台为主,技 ...

  5. redux、immutablejs和mobx性能对比(三)

    四.我的结论 通过第三部分的数据数据分析,我觉得我们可以得到以下结论: 无论是在开发环境还是测试环下页面的首次加载速度结果都是:redux>immutablejs>mobx,但是他们之间的 ...

  6. 微信小程序里使用 Redux 状态管理

    微信小程序里使用 Redux 状态管理 前言 前阵子一直在做小程序开发,采用的是官方给的框架 wepy , 如果还不了解的同学可以去他的官网查阅相关资料学习:不得不说的是,这个框架确相比于传统小程序开 ...

  7. Redux 的困扰与如何技术选型

    文章的名字我想了很久,备选项有"我再不推荐 Redux","Redux 为什么令我头疼","Redux 进化启示录"等等.通过这一系列名字我 ...

  8. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  9. 通过一个demo了解Redux

    TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...

  10. RxJS + Redux + React = Amazing!(译二)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...

随机推荐

  1. KindleVocab 教程,Kindle导出查词记录成文本文档,Kindle导出查询单词记录导入Anki

    程序功能 因本人使用Kindle Mate导出觉得复杂,特意写了个自用的导出程序(有linux版本和win两个版本). 所以 KindleVocab 只有一个作用:导出Kindle查询过的生词和生词所 ...

  2. 2023NOIP A层联测26 T3 tour

    2023NOIP A层联测26 T3 tour 有意思的树上主席树. 思路 首先考虑一个点 \(p\) 能计入答案的情况,就是 \(dis(x,p)-a_p \ge a_p\). 我们把 \(x \t ...

  3. nginx配置php-fpm虚拟主机站点

    ubuntu下安装nginx 很简单 sudo apt-get install nginx 然后安装php-fpm 我这本地php7.4所以这么写 sudo apt search php7.4-fpm ...

  4. Docker私有仓库操作----命令行

    查看所有镜像 http://10.206.29.162:5000/v2/_catalog {"repositories":["dashboard"," ...

  5. golang之http请求库go-resty

    github: https://github.com/go-resty/resty go-resty 特性# go-resty 有很多特性: 发起 GET, POST, PUT, DELETE, HE ...

  6. Kafka可视化工具之Kafka Tool

    官网: https://www.kafkatool.com/download.html Kafka Tool是一个用于管理和使用Apache Kafka集群的GUI应用程序. Kafka Tool提供 ...

  7. 终端工具之Tabby

    我工作中用的最多的工具之一就是「终端连接工具」了,因为经常和 Linux 服务器打交道,经常在上面跑代码.排查系统问题等等. Windows 系统最常用的就是 Xshell 这款终端工具了,但是它只能 ...

  8. BUU get_started_3dsctf_2016

    先checksec一下 32位程序,没开PIE,再观察一下主函数 gets函数有可能是栈溢出,再观察一下后门函数 方法一: 考虑栈溢出后直接跳转到if判断后面的语句,进而跳过if条件判断 from p ...

  9. Net中手写 事件总线 发布订阅消息

    Net 手写 事件总线 发布订阅消息 前言 今晚打老虎 事件总线是对发布-订阅模式的一种实现.它是一种集中式事件处理机制,允许不同的组件之间进行彼此通信而又不需要相互依赖,达到一种解耦的目的.(项目的 ...

  10. 企架布道:中电金信应邀出席2023佛山敏捷之旅暨DevOps Meetup

    近日,2023佛山敏捷之旅暨DevOps Meetup活动顺利举行,本次活动以助力大湾区金融和互联网企业敏捷DevOps实施和效能提升为主题,共设立 2个会场,16个话题分享,200余位金融.互联网企 ...