redux常见概念

ByteWaltz
• 阅读 5509

redux

redux常见概念

gif地址

  1. Web 应用是一个状态机,视图与状态是一一对应的。

  2. 所有的状态,保存在一个对象里面。

redux不依赖于react

state

就是app中数据组成的树,也是一个普通的js对象。树的结构根据应用的需要自行决定,官方推荐的方式是分为三种数据:

  1. 后端提供的应用数据

  2. 应用状态数据 (某条数据是否选中)

  3. ui组件的数据(弹窗是否打开)

action

action是一个描述“发生了什么”的普通对象
action是我们开发的应用程序和store间通信的信息,它就是普通的js对象,结构是自定义的,信息量应尽可能小。
例如:

{
  type: 'ADD_NEWS',
  text: '这是一条新闻'
}

action creator

action创建函数

function addNews(text) {
  return {
    type: 'ADD_NEWS',
    text
  }
}

reducer

reducer是根据action来返回一个全新state的纯函数。

function newsReducer(state = initialState, action) {
  switch (action) {
      case: 'ADD_NEWS':
        return [...state, text]
        break;
    default:
        return state;
  }
}

store

store只是把actions和reducers联系在一起的对象,并不是传统意义上象征数据的东西。

const store = createStore(rootReducer, defaultState)

提供 getState() 方法获取 state
提供 dispatch(action) 方法更新 state; store.dispatch(addNews('这是一条新闻'))
通过 subscribe(listener) 注册监听器
通过 subscribe(listener) 返回的函数注销监听器。

react-redux

容器组件(container)和展示组件(component)

component只关注展示层。
container是通过connect方法把redux和展示组件关联起来的东西。

combineReducers

combineReducers(reducers)
传入reducers作为参数, reducers是一个object,如 {news: function() {...}, blogs: function() {...}}
返回一个遍历执行所有reducers的reducer函数,每个reducer只处理state中对应自己key的部分.

bindActionCreators

bindActionCreator

function bindActionCreator(actionCreator, dispatch) {
  return (...args) => dispatch(actionCreator(...args))
}

bindActionCreators就是把多个actionCreator变成会去执行dispatch的函数,并且返回这个对象。

connect

连接 React 组件与 Redux store。连接操作不会改变原来的组件类。反而返回一个新的已与 Redux store 连接的组件类。

1.mapStateToProps
如果定义该参数,组件将会监听 Redux store 的变化。任何时候,只要 Redux store 发生改变,mapStateToProps 函数就会被调用。该回调函数必须返回一个纯对象,这个对象会与组件的 props 合并。如果你省略了这个参数,你的组件将不会监听 Redux store。如果指定了该回调函数中的第二个参数 ownProps,则该参数的值为传递到组件的 props,而且只要组件接收到新的 props,mapStateToProps 也会被调用(例如,当 props 接收到来自父组件一个小小的改动,那么你所使用的 ownProps 参数,mapStateToProps 都会被重新计算)

// 把state上的todos绑定到 组件.props.todos
function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps)(TodoApp)

2.mapDispatchToProps
(Object or Function): 如果传递的是一个对象,那么每个定义在该对象的函数都将被当作 Redux action creator,而且这个对象会与 Redux store 绑定在一起,其中所定义的方法名将作为属性名,合并到组件的 props 中。如果传递的是一个函数,该函数将接收一个 dispatch 函数,然后由你来决定如何返回一个对象,这个对象通过 dispatch 函数与 action creator 以某种方式绑定在一起(提示:你也许会用到 Redux 的辅助函数 bindActionCreators())。如果你省略这个 mapDispatchToProps 参数,默认情况下,dispatch 会注入到你的组件 props 中。如果指定了该回调函数中第二个参数 ownProps,该参数的值为传递到组件的 props,而且只要组件接收到新 props,mapDispatchToProps 也会被调用。

export function mapDispatchToProps(dispatch) {
  return bindActionCreators(actionCreators, dispatch);
}

// 下面两种方式效果一致
var App = connect(mapStateToProps, actionCreators)(Main);
var App = connect(mapStateToProps, mapDispatchToProps)(Main);

Provider

包裹Provider让所有container都能访问store

store.dispatch(action)

store.dispath(action)会执行reducer(currentState, action)并return action。原生的dipatch只支持普通js对象来作为参数,否则会报错。

redux middleware

它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。(?)
其实就是在dispatch前后做一些额外的事情的一个函数,这个函数就是middleware, 有多个middlewares也就是嵌套地执行这多个函数。

const logger = ({ dispatch, getState }) => next => action => {
  console.log('dispatching', action)
  let result = next(action)
  console.log('next state', getState())
  return result
}


export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

const middlewares = [logger]

const store = createStore(
  reducer,
  applyMiddleware(...middlewares)
)

redux thunk

通过redux middleware实现支持dispatch一个函数。

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

stackoverflow上的介绍。
容器组件和展示组件相分离

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
徐小夕 徐小夕
4年前
《彻底掌握redux》之开发一个任务管理平台(上)
前言redux是上手react开发的必经之路,也是目前react项目中使用的最流行状态管理库。虽然我们不使用redux也可以通过react的state和父子props进行基本的数据通信和项目开发,但是对于一个大型项目而言,往往考虑的更多的是代码结构和组件之间的通信,我们需要一种很优雅且有利于扩展的方式去开发我们的复杂系统,所以这种情况下使用redux是最佳
Stella981 Stella981
3年前
Redux异步解决方案之Redux
前段时间,我们写了一篇Redux源码分析的文章(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fjuejin.im%2Fpost%2F6845166891682512909),也分析了跟React连接的库ReactRedux的源码实现(https://www.oschina
Stella981 Stella981
3年前
Redux入门实战——todo
1.前言在之前的博客中,我写了一篇关于todolist实现的博客,一步一步详细的记录了如何使用基础的React知识实现一个React单页面应用,通过该篇文章,能够对React入门开发有一个直观的认识和粗浅的理解。近期,个人学习了一下Redux,又将该项目使用ReactRedux的方式进行了实现。本片内容记录以下实践的过程。通过本实例,
Stella981 Stella981
3年前
Redux入门到使用。
!(https://oscimg.oschina.net/oscnet/c7b0cf8db4ed63eccfdfe3b7d711ec72da6.gif)简介Redux是针对JavaScript应用的可预测状态容器。如果熟悉设计模式之观察者模式理解起来就简单了。就是将你在其他组件中需要用到的数据放到一个容器中,那么组件就可以从其中取放
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这