react&redux基礎

Redux 主要分爲三個部分 ActionReducer、及 Storejavascript

原理:java

  • view直接觸發dispatchreact

  • action發送到reducer中後,根節點上會更新 state,改變全局viewredux

本案例以一個提到TODOLIST爲案例。app

Action

Redux 中,action 主要用來傳遞操做 State 的信息,只是一種命令,並無實際改變stateide

咱們約定,action 內必須使用一個字符串類型的 type 字段來表示將要執行的動做。type 屬性是必要的,除了 type 字段外,action 對象的結構徹底取決於你,建議儘量簡單。type 通常用來表達處理 state 數據的方式。函數

好比添加todoactionui

const ADD_TODO = 'ADD_TODO'
{
  type: ADD_TODO,
  text: 'Build my first Redux app'
}

這個動做須要改變哪些屬性就傳遞這些屬性。spa

建立函數

若是有多個數據是一樣的動做,那麼咱們就須要一個通用的函數來傳遞數據。在 Redux 中的 action 建立函數只是簡單的返回一個 action:code

//actions
export const ADD_TODO = 'ADD_TODO'
export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

或者

//actions
export const ADD_TODO = 'ADD_TODO'
export const addTodo = (text) => {
  return {
    type: ADD_TODO,
    text
  }
}

在組件的事件中,Redux 中只需把 action 建立函數的結果傳給 dispatch() 方法便可發起一次 dispatch 過程。

dispatch(addTodo(text))

或者

const boundAddTodo = (text) => dispatch(addTodo(text))
boundAddTodo(text);
bindActionCreators

如上所示,咱們每次都須要調用時dispatch這個action。

在 React 組件中,若是你但願讓組件經過調用函數來更新 state,能夠經過使用 const actions = bindActionCreators(FilmActions, dispatch); 將 actions 和 dispatch 揉在一塊兒,成爲具有操做 store.state 的 actions。

Reducer

Action 只是描述了有事情發生了這一事實,並無指明應用如何更新 state。而這正是 reducer 要作的事情。

當明確action的任務,就能夠開始編寫 reducer,並讓它來處理以前定義過的 action。

//reducers
import { addTodo,ADD_TODO } from './actions'

function todoApp(state = initialState, action) {
  switch (action.type) {
    case ADD_TODO:
      return Object.assign({}, state, {
        text: action.text
      })
    default:
      return state
  }
}

注意:

  • 不要修改 state。 使用 Object.assign() 新建了一個副本。爲了對ES7提案對象展開運算符的支持, 也能夠使用 { ...state, ...newState } 達到相同的目的。

  • 在 default 狀況下返回舊的 state。遇到未知的 action 時,必定要返回舊的 state。

  • reducer中的一個fun在store裏做爲一個對象存儲。

combineReducers

combineReducers() 所作的只是生成一個函數,這個函數來調用你的一系列 reducer,每一個 reducer 根據它們的 key 來篩選出 state 中的一部分數據並處理,而後這個生成的函數再將全部 reducer 的結果合併成一個大的對象。

import { combineReducers } from 'redux';

const todoApp = combineReducers({
  todoApp
})

export default todoApp;

Store

Store 就是把actionreducer聯繫到一塊兒的對象。Store 有如下職責:

  • 維持應用的 state

  • 提供 getState() 方法獲取 state

  • 提供 dispatch(action) 方法更新 state

  • 經過 subscribe(listener) 註冊監聽器;

  • 經過 subscribe(listener) 返回的函數註銷監聽器。

Redux 應用只有一個單一的 store。當須要拆分數據處理邏輯時,你應該使用 reducer組合 而不是建立多個 store

咱們使用 combineReducers() 將多個 reducer 合併成爲一個。如今咱們將其導入,並傳遞 createStore()

import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)
Middleware

redux中的middleware仍是比較簡單的,它只是針對於dispatch方法作了middleware處理;也就是說,只接受一個action對象;

import  createLogger from 'redux-logger';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers';
const logger = createLogger();
let thunkStore = applyMiddleware(thunk,logger)(createStore);
let store = thunkStore(reducers);

connect

connect(mapStateToProps, mapDispatchToProps, mergeToProps)(App);

第一個函數接收store中state和props,使頁面能夠根據當前的store中state和props返回新的stateProps;
第二個函數接收store中的dispatch和props,使頁面能夠複寫dispatch方法,返回新的dispatchProps
第三個函數接收前2個函數生成的statePropsdispatchProps,在加上原始的props,合併成新的props,並傳給原始根節點的props

const mapStateToProps = (state, ownProps) => {
  return {
    active: ownProps.filter === state.visibilityFilter
  }
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onClick: () => {
      dispatch(setVisibilityFilter(ownProps.filter))
    }
  }
}

const FilterLink = connect(
  mapStateToProps,
  mapDispatchToProps
)(Link)

Provider

<Provider store> 使組件層級中的 connect() 方法都可以得到 Redux store。正常狀況下,你的根組件應該嵌套在 <Provider> 中才能使用 connect() 方法。

react-redux首先提供了一個Provider,能夠將從createStore返回的store放入context中,使子集能夠獲取到store並進行操做;

Connect 組件須要 store。這個需求由 Redux 提供的另外一個組件 Provider 來提供。源碼中,Provider 繼承了 React.Component,因此能夠以 React 組件的形式來爲 Provider 注入 store,從而使得其子組件可以在上下文中獲得 store 對象。

<Provider store={store}>
    <App/>
</Provider>
相關文章
相關標籤/搜索