内容简介:在 React 的学习和开发中,如果 state (状态)变得复杂时(例如一个状态需要能够在多个 view 中使用和更新),使用 Redux 可以有效地管理 state,使 state tree 结构清晰,方便状态的更新和使用。当然,Redux 和 React 并没有什么关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。只是对我来说目前主要需要在 React 中使用,所以在这里和 React 联系起来便于理解记忆。
在 React 的学习和开发中,如果 state (状态)变得复杂时(例如一个状态需要能够在多个 view 中使用和更新),使用 Redux 可以有效地管理 state,使 state tree 结构清晰,方便状态的更新和使用。
当然,Redux 和 React 并没有什么关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。只是对我来说目前主要需要在 React 中使用,所以在这里和 React 联系起来便于理解记忆。
数据流
Action
只是描述 state (状态)更新的动作,即“发生了什么”,并不更新 state。
const ADD_TODO = 'ADD_TODO'
{
type: ADD_TODO,
text: 'Build my first Redux app'
}
- type:必填,表示将要执行的动作,通常会被定义成字符串常量,尤其是大型项目。
- 除了 type 外的其他字段:可选,自定义,通常可传相关参数。例如上面例子中的 text。
Action 创建函数
简单返回一个 Action:
function addTodo(text) {
return {
type: ADD_TODO,
text
}
}
dispatch Action:
dispatch(addTodo(text)) // 或者创建一个 被绑定的 action 创建函数 来自动 dispatch const boundAddTodo = text => dispatch(addTodo(text)) boundAddTodo(text)
帮助生成 Action 创建函数的库(对减少样板代码有帮助):
Reducer
说明在发起 action 后 state 应该如何更新。
是一个纯函数:只要传入参数相同,返回计算得到的下一个 state 就一定相同。
(previousState, action) => newState
注意,不能在 reducer 中执行的操作:
- 修改传入的参数
- 执行有副作用的操作,如 API 请求和路由跳转
- 调用非纯函数,如 Date.now() 或 Math.random()
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
}
]
case TOGGLE_TODO:
return state.map((todo, index) => {
if (index === action.index) {
return Object.assign({}, todo, {
completed: !todo.completed
})
}
return todo
})
default:
return state
}
}
const todoApp = combineReducers({
visibilityFilter,
todos
})
export default todoApp
Store
Redux 应用只有一个单一的 store。
- 维持应用的 state;
- 提供 getState() 方法获取 state;
- 提供 dispatch(action) 方法更新 state;
- 通过 subscribe(listener) 注册监听器;
- 通过 subscribe(listener) 返回的函数注销监听器。
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(
todoApp,
[preloadedState], // 可选,state 初始状态
enhancer
)
import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import DevTools from './containers/DevTools'
import reducer from '../reducers/index'
export default function configureStore() {
const store = createStore(
reducer,
compose(
applyMiddleware(thunk),
DevTools.instrument()
)
);
return store;
}
react-redux
connect() 方法( mapStateToProps 、 mapDispatchToProps )
替代 store.subscribe() ,从 Redux state 树中读取部分数据,并通过 props 提供给要渲染的组件。
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as actions from './actions';
class App extends Component {
handleAddTodo = () => {
const { actions } = this.props;
actions.addTodo('Create a new todo');
}
render() {
const { todos } = this.props;
return (
<div>
<Button onClick={this.handleAddTodo}>+</Button>
<ul>
{todos.map(todo => (
<Todo key={todo.id} {...todo} />
))}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
return {
todos: state.todos
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
addTodo: actions.addTodo
}, dispatch)
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
Provider 组件
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import configureStore from './store/configureStore'
import App from './components/App'
render(
<Provider store={configureStore()}>
<App />
</Provider>,
document.getElementById('root')
API 请求
一般情况下,每个 API 请求都需要 dispatch 至少三种 action:
- 通知 reducer 请求开始的 action
{ type: 'FETCH_POSTS_REQUEST' }
reducer 可能会{...state, isFetching: true} - 一种通知 reducer 请求成功的 action
{ type: 'FETCH_POSTS_SUCCESS', response: { ... } }
reducer 可能会{...state, isFetching: false, data: action.response} - 一种通知 reducer 请求失败的 action
{ type: 'FETCH_POSTS_FAILURE', error: 'Oops' }
reducer 可能会{...state, isFetching: false, error: action.error}
使用 middleware 中间件实现网络请求:
redux-thunk
通过使用指定的 middleware,action 创建函数除了返回 action 对象外还可以返回函数。这时,这个 action 创建函数就成为了 thunk。
路由跳转( react-router )
参考资料:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Probabilistic Method Second Edition
Noga Alon、Joel H. Spencer / Wiley-Blackwell / 2000 / $121.95
The leading reference on probabilistic methods in combinatorics-now expanded and updated When it was first published in 1991, The Probabilistic Method became instantly the standard reference on one......一起来看看 《The Probabilistic Method Second Edition》 这本书的介绍吧!
UNIX 时间戳转换
UNIX 时间戳转换
RGB CMYK 转换工具
RGB CMYK 互转工具