redux-理解

1.概念javascript

通俗理解reduxhtml

2.actionjava

(1)本质是一个JS对象;react

3.reducerredux

(1)Store 收到 Action 之后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫作 Reducer。数组

(2)接受action和当前参数state做为参数,而后返回一个新的statedom

const reducer = function (state, action) {
  // ...
  return new_state;
};

例子:异步

const defaultState = 0;
const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};

const state = reducer(1, {
  type: 'ADD',
  payload: 2
});

实际应用中,Reducer 函数不用像上面这样手动调用,store.dispatch方法会触发 Reducer 的自动执行。为此,Store 须要知道 Reducer 函数,作法就是在生成 Store 的时候,将 Reducer 传入createStore方法。ide

import { createStore } from 'redux';
const store = createStore(reducer);

createStore接受 Reducer 做为参数,生成一个新的 Store。之后每当store.dispatch发送过来一个新的 Action,就会自动调用 Reducer,获得新的 State。函数

// State 是一个对象
function reducer(state, action) {
  //后面的thingTochange会覆盖前面的state
  return Object.assign({}, state, { thingToChange });
  // 或者,对象展开符的对象合并,后面有的属性会覆盖前面的
  return { ...state, ...newState };
}

// State 是一个数组
function reducer(state, action) {
  //在数组里面添加一个项目,若是后面的也是一个数组,直接...new Item
  return [...state, newItem];
}

(3)reducer是一个纯函数。

一样的输入一定致使一样的输出。

4.store

(1)createStore函数接受另外一个函数做为参数,返回新生成的Store对象 。store对象包含全部数据。

(2)一个state对应一个view,只要state相同,view就相同,因此state的变化会致使view的变化。

         用户接触不到state,只接触view,因此,state的变化是view致使的,action是view发出的通知,表示State应该要变化了。

        action是一个对象,type属性必须,其余能够自由设置,通常会有payload action描述当前发生的事情,改变State的惟一办法,就是使用Action。

         store.dispatch()是view发出action的惟一方法。

(3)

Store 容许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。

import { createStore } from 'redux';
const store = createStore(reducer);

store.subscribe(listener);

显然,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listen,就会实现 View 的自动渲染。

store.subscribe方法返回一个函数,调用这个函数就能够解除监听。

let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

unsubscribe();

5.react-redux

react项目中,能够直接使用redux,也可使用react-redux,后者需掌握额外的API,而且遵循它的组件拆分规范。

(1)react-redux将全部组件分为:UI组件和容器组件

UI组件最大特征是没有this.state(无状态),只负责UI的呈现,不带有任何业务逻辑,不使用redux的API;

容器组件:负责管理数据和业务逻辑,不负责UI呈现,带有内部状态,使用redux的API。

使用react-redux,若是一个组件既有UI又有逻辑,那么将它拆分红下面结构:外面是一个容器组件,里面包含一个UI组件,前者负责与外部通讯,将数据传给后者,由后者渲染出视图。

react-redux规定:全部UI组件都由用户提供,容器组件则由react-redux自动生成,也就是说,用户负责视觉层,状态管理则所有交给它。

(2)connect()

react-redux提供connect方法,用于从UI组件生成容器组件。connect的意思,就是将二者连起来。

import { connect } from 'react-redux'

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

mapStateToProps:输入逻辑,即将state映射到 UI 组件的参数(props)。做为函数,返回一个对象,里面的每个键值对就是一个映射。

mapStateToProps会订阅 Store,每当state更新的时候,就会自动执行,从新计算 UI 组件的参数,从而触发 UI 组件的从新渲染。

mapStateToProps的第一个参数老是state对象,还可使用第二个参数,表明容器组件的props对象。

使用ownProps做为参数后,若是容器组件的参数发生变化,也会引起 UI 组件从新渲染。

connect方法能够省略mapStateToProps参数,那样的话,UI 组件就不会订阅Store,就是说 Store 的更新不会引发 UI 组件的更新。

 

mapDispatchToProps()

mapDispatchToPropsconnect函数的第二个参数,用来创建 UI 组件的参数到store.dispatch方法的映射。也就是说,它定义了哪些用户的操做应该看成 Action,传给 Store。它能够是一个函数,也能够是一个对象。

若是mapDispatchToProps是一个函数,会获得dispatchownProps(容器组件的props对象)两个参数。

mapDispatchToProps做为函数,应该返回一个对象,该对象的每一个键值对都是一个映射,定义了 UI 组件的参数怎样发出 Action。

若是mapDispatchToProps是一个对象,它的每一个键名也是对应 UI 组件的同名参数,键值应该是一个函数,会被看成 Action creator ,返回的 Action 会由 Redux 自动发出。

(3)<Provider>组件

connect方法生成容器组件之后,须要让容器组件拿到state对象,才能生成 UI 组件的参数。

一种解决方法是将state对象做为参数,传入容器组件。可是,这样作比较麻烦,尤为是容器组件可能在很深的层级,一级级将state传下去就很麻烦。

React-Redux 提供Provider组件,可让容器组件拿到state

import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'

let store = createStore(todoApp);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Provider在根组件外面包了一层,这样一来,App的全部子组件就默认均可以拿到state了。

6.问题E

(1)为何叫作reducer?

   由于它能够做为数组的reduce方法的参数。

const actions = [
  { type: 'ADD', payload: 0 },
  { type: 'ADD', payload: 1 },
  { type: 'ADD', payload: 2 }
];

const total = actions.reduce(reducer, 0); // 3

   (2)什么叫纯函数?

一样输入致使一样输出。

一些约束:

  • 不得改写参数
  • 不能调用系统 I/O 的API
  • 不能调用Date.now()或者Math.random()等不纯的方法,由于每次会获得不同的结果。

(3)redux怎么解决异步的问题?

Action 发出之后,Reducer 当即算出 State,这叫作同步;Action 发出之后,过一段时间再执行 Reducer,这就是异步。

依靠使用中间件(middleware)。

(4)Provider的原理

是React组件的context属性。

store放在了上下文对象context上面,而后子组件就能够从context拿到store。

Provider的惟一功能就是传入store对象