您的位置:首页 > Web前端 > React

React Native之Redux使用详解之Actions(29)

2016-07-10 20:54 956 查看

React Native之Redux使用详解(29)

(一)前言

1.1 简要介绍

什么是React Native的Redux,其实简单理解就是为FaceBook为React Native应用开发专门开发的一套数据访问规则,其他不多说,这篇文章旨在说明怎么使用。

1.2 三个规则

1.2.1 单源

整个App的state呗存储在一个对象树中,即 Store。

console.log(store.getState())

/* Prints
{
visibilityFilter: 'SHOW_ALL',
todos: [
{
text: 'Consider using Redux',
completed: true,
},
{
text: 'Keep all state in a single tree',
completed: false
}
]
}
*/


1.2.2 State是只读的

唯一去转变state的方式是发出一个action,action是描述发生什么了的对象。

通过以下代码去转变State,就是通过dispatch()方法分发Action。

store.dispatch({
type: 'COMPLETE_TODO',
index: 1
})

store.dispatch({
type: 'SET_VISIBILITY_FILTER',
filter: 'SHOW_COMPLETED'
})


1.2.3 状态改变只能由纯函数导致

Reducers就是一系列纯函数,它们获取到前一状态state对象和一个action,然后返回新的state对象。记住返回的是新的state对象,不是经过改变过的前一个state对象。你可以前期使用一个单一reducer,随着你的app的成长,分解它成更小多个reducers来管理指定部分的state树。因为 reducers仅仅是一系列函数,你能够控制它们被调用的顺序,传递额外的数据,或者甚至创建可重复利用的reducers去执行公共任务。例如:标页码。

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
}
]
case 'COMPLETE_TODO':
return state.map((todo,index) => {
if (index === action.index) {
return
Object.assign({},todo,{
completed: true
})
}
return todo
})
default:
return state
}
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)


(二)基本使用

2.1 Actions

2.1.1 Actions 介绍

首先,我们定义一些actions。它们是Store的唯一数据源, 可以通过store.dispatch()函数发送它们到Store。

下面是一个例子,定义action,该 action 展示添加一个新的 todo item:

const ADD_TODO = 'ADD_TODO'


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


Action是纯粹的JavaScript对象。Action必须有一个 type 属性,type能指示被执行的action的类型。Type应该典型地被定义为string 常量。一旦你的app应用是足够大,你可能尝试分解它们成为一些模块。

import { ADD_TODO, REMOVE_TODO } from '../actionTypes'


【特别注意】

对于一个小的工程,你没有必要定义action type常量在分离文件中,或者甚至不用定义常量, 使用string字面量(string literals)于action的type属性上可能是更简易的做法。然而,对于更大的代码项目明确地申明常量可以带来一些好处。阅读Reducing Boilerplate获取更多保持代码整洁的实际tips。

除了 type, 一个action对象的结构完全取决于你自己。如果你感兴趣,请查看Flux Standard Action获得更多建设性意见对于怎么构建actions。

例如下面的代码, 我们将添加一个action类型来描述用户待办的事项已完成。我们通过index来相关联一个特殊的 todo,因为我们存储它们在一个array中。在真实的app中,每次一些新的东西被创建,生成一个唯一的 ID是更明智的。

{
type: TOGGLE_TODO,
index: 5
}


在每个action中, 传递尽可能少的数据是一个很好的做法。例如:传递index是更好的做法比传递整个状态state对象。

最后,我们将添加一个action去改变当前显示的内容类型。

{
type: SET_VISIBILITY_FILTER,
filter: SHOW_COMPLETED
}


2.1.2 Action Creators(Action创建器)

Action creators 确切的是创建action的函数。很容易混淆“action”和“action creator”.

在Redux中,action creators简单地返回一个action:

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


这种方式让更便捷和易于测试。

在传统Flux中, action创建器经常触发一个dispatch(),如下:

function addTodoWithDispatch(text) {
const action = {
type: ADD_TODO,
text
}
dispatch(action)
}


在Redux中,并不是这样的。

而是,传入产生action的函数到dispatch()函数中,代码如下:

dispatch(addTodo(text))
dispatch(completeTodo(index))


或者,你能创建一个闭包去自动分发:

const boundAddTodo = (text) => dispatch(addTodo(text))
const boundCompleteTodo = (index) => dispatch(completeTodo(index))


现在,你可以直接调用:

boundAddTodo(Text)
boundCompleteTodo(index)


能够直接通过 store.dispatch()访问dispatch()函数,但是更可能地,你通过利用helper去访问它,例如react-redux的connect()类似。你能利用bindActionCreators()去自动绑定许多action Creators到dispatch()函数。

Action creators也能异步执行,并且伴有有副作用。你可以阅读进阶指南advanced tutorial的异步actions async actions 学习怎么操作AJAX响应和整合action creators到异步控制流中。除非你已经完成基础指南,不要跳过基础篇直接到 async actions,由于它覆盖其他重要概念是进阶指南和async actions的必要条件。

2.1.3 Source Code

actions.js

/*
*  action types
*/

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/**
* Other constants
*/
export const VisibilityFilters = {
SHOW_ALL: 'SHOW_ALL',
SHOW_COMPLETED:'SHOW_COMPLETED',
SHOW_ACTIVE:'SHOW_ACTIVE'
}

/**
* Action creators
*/

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

export function toggleTodo(index) {
return { type: TOGGLE_TODO, index }
}

export function setVisibilityFilter(filter) {
return { type: SET_VISIBILITY_FILTER, filter }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: