安装

npm install redux

核心概念

redux将整个应用的state存储到一个store中,当用户触发一个action的时候,通过调用store.dispatch(action)来触发sotre中定义好的 reducers 最终更新引用的state。

  1. store 用来存储整个应用的 state
  2. state 一个用来描述应用状态的对象
  3. action 一个对象,用来描述程序发生的动作
  4. reducer 是更改state的纯函数接受 state 和action参数最后返回新的state

下面我会对每个概念进行介绍

三大原则

  1. 单一的数据来源,整个应用程序的状态存储在单个store 中
  2. state 对象是只读的,改变state 的唯一方式是发出一个action
  3. 如何通过action改变state,通过编写春函数reducer 来实现

Actions

action是将数据发送的store的有效负载,他们是store数据的唯一来源通过 store.dispatch()将数据发送的store

action 是一个普通的js对象,action必须指定一个 type 属性用来描述执行的操作。

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

Action Creators

action creators 是返回一个action 的方法,这样写可以方便开发和测试。

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

dispatch(addTodo('eat'))

Reducers

Reducers是指定状态树如何响应 dispatch 到store 的action的,action只是用来描述发生的动作,不描述状态的变化。

首先确定state的数据的格式

{
  todos: [
    {
      text: 'Consider using Redux',
      completed: true
    }
  ]
}

确定state的数据格式之后我们就可以编写一个reducer,reducer 是一个纯函数接收state和action返回新的state

const initialState = {
  todos: []
}

function todoApp(state = initialState, action) {
  switch (action.type) {
    case 'ADD_TODO':
      return Object.assign({}, state, {
        todos: [
          ...state.todos,
          {
            text: action.text,
            completed: false
          }
        ]
      })
    default:
      return state
  }
}
注意我们使用Object.assign()返回一个新的状态,不改变参数中的state 的值

分割 Reducers

当我们应用程序的action比较多每个action在reducers中的逻辑比较复杂的时候,如果还像我们上面一直使用 switch case 可以想象我们的reducers会变的非常的长,此时我们就需要对一些复杂的操作进行分割,分割的规则是根据 state 的节点操作进行分割,针对每个节点的操作写一个reducers然后使用 combineReducers 方法进行合并。

例如

import { combineReducers } from 'redux'
import {
  ADD_TODO,
  TOGGLE_TODO,
  SET_VISIBILITY_FILTER,
  VisibilityFilters
} from './actions'
const { SHOW_ALL } = VisibilityFilters

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    default:
      return state
  }
}

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp

Store

在redux 应用程序中只能有一个store,使用store可以将上面的reducers和actions进行组合,然后进行操作。

创建一个store

redux提供了一个createStore接收一个reducers参数,最终返回一个store,我们将之前定义好的reducers引入,然后传入createStore 就可以了。

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

store 提供的方法

  1. getState() 获取store中的状态树
  2. dispatch(action) 发送action 更新action
  3. subscribe(listener) 订阅监听返回一个unsubscribe函数用来取消订阅

react-redux

安装

npm install --save react-redux

Provider

<provider /> 是redux提供的一个组件,这个组件 有一个props store (上面文档中创建出来的store) , 这个组件可以使,使用connect()函数嵌套的组件能访问redux中的store。

用法

import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'

import { App } from './App'
import createStore from './createReduxStore'

const store = createStore()

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

connect

connect函数用于把redux 的store 和react 的组件连接到一起,他返回的是一个包装函数,这个函数的参数是一个react的组件,这个函数将会返回一个 包装组件。

function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)

例子

import { addTodo } from './actionCreators'

const mapDispatchToProps = {
  addTodo
}
const mapStateToProps = (state, ownProps) => ({
  todo: state.todos[ownProps.id]
})
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoApp)

mapStateToProps?: (state, ownProps?) => Object

state为redux的状态树,ownProps是链接组件的props

如果此方法有一个参数,在redux的state发生变化的时候会调用函数,如果此方法有两个参数,此方法将会在连接组件的props或者redux的state发生变化的时候调用。

此方法返回一个对象, 此对象(通常称为stateProps)将合并为连接组件的props 。如果定义mergeProps,它将作为mergeProps的第一个参数提供。

mapDispatchToProps?: Object | (dispatch, ownProps?) => Object

dispatch 即 store中的dispatch 通过传入一个action给变store中的state数据

ownProps 即 链接组件的 props

您的mapDispatchToProps函数应返回一个对象。对象的每个字段都应该是一个函数,调用哪个函数可以dispatch 一个action 到store。

mapDispatchToProps函数的返回被视为dispatchProps。它将作为props合并到您连接的组件。如果定义mergeProps,它将作为mergeProps的第二个参数提供。

mergeProps?: (stateProps, dispatchProps, ownProps) => Object

如果指定,则定义如何确定自己的包装组件的最终props。如果您不提供mergeProps,则默认情况下,您的包装组件会收到{... ownProps,... stateProps,... dispatchProps}。

mergeProps的返回值称为mergedProps,字段将用作包装组件的props。

options?: Object

暂未使用

参阅文档


曹飞龙
167 声望8 粉丝

进取・坚韧・开放・影响