Open eyasliu opened 8 years ago
应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。惟一改变 state 的办法是触发 action,一个描述发生什么的对象。为了描述 action 如何改变 state 树,你需要编写 reducers。
Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般使用 store.dispatch() 将action 传到store
store.dispatch()
const action = { type: 'ADD_TODO', text: 'Build my first Redux app' } store.dispatch(action)
一个action必须有type字段,描述action做的事情,其他字段都为可选项,是action携带的数据,只作为传递数据用途。
type
Action 创建函数 就是生成 action 的方法。可以简单的理解为调用这个函数就会创建action并且自动调用store.dispatch()。当我们使用react-redux工具时,可以自动绑定dispatch,所以函数可以简化为这样:
react-redux
function addTodo(text) { return { type: 'ADD_TODO', text } } // 在组件中调用,自动dispatch this.props.addTodo('test task')
redux会dispatch函数的返回值
action 只是描述了有事情发生了这一事实,reducer根据action的描述怎么去更新状态。reducer就是一个纯函数,接收旧的state和action,返回新的state。使用函数默认值设置初始状态。
function todo(state = {todos: []}, action){ switch(action.type){ case 'ADD_TODO': return { ...state, todos: [ ...state.todos, { id: state.todos.length + 1, text: action.text } ] } default: return state; } }
注意:永远不要在reducer做这些事
不修改state,直接返回一个新对象state
谨记 reducer 一定要保持纯净。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算
应用一旦复杂了,reduer会非常长,为了更好的模块化管理,拆分成多个小reducer,然后合并。Redux 提供了 combineReducers() 工具类合并reducer。但只能有一个根reducer,相当于react组件只有一个根标签。
import { combineReducers } from 'redux'; const todoCrud = (state, action) => {} const todoVisable = (state, action) => {} const todo = combineReducers({ crud: todoCrud, visable: todoVisable }) export default todo;
action 来描述“发生了什么”,reducers 来根据 action 更新 state 。Store就是把他们联系到一起的对象。Redux 应用只有一个单一的 store
redux 提供 createStore() 工具创建store,接收根reducer作为参数
createStore()
import {createStore} from 'redux'; import rootReducer from './reducers'; const store = createStore(rootReducer)
Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。他只是一个状态管理工具而已。
redux与react搭配使用react-redux工具。
将 <Provider /> 包围需要使用redux状态的组件。如根组件。provider 需要传递 store 进去。
<Provider />
import { render } from 'react-dom'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; import App from './containers/App'; import todoApp from './reducers'; let store = createStore(todoApp); let rootElement = document.getElementById('root') render( <Provider store={store}> <App /> </Provider>, rootElement )
在Provider包围的范围内,通过 react-redux 提供的 connect() 方法将包装好的组件连接到Redux。传入组件需要的状态与action 生成函数。
connect()
bindActionCreators 可以将普通的函数自动绑定变为 action生成函数
bindActionCreators
import {connect, bindActionCreators} from 'redux'; import {addTodo} from './actions'; class App extends React.Component{ handlerClick(e){ this.props.todos // 来自于redux的 state.todos this.props.addTodo('this is my task') // 调用 action 生成函数 } render(){ return <div onClick={this.handlerClick}></div> } } // 将 reudx 的状态传递给组件,可在组件的props获取 function mapStateToProps(state){ return { todos: state.todos } } // 将普通函数绑定转化为action生成器 function mapDispatchToProps(dispatch){ return bindActionCreators({addTodo}, dispatch); } // 连接 export default connect(mapStateToProps, mapDispatchToProps)(App)
我们可以使用 es7 的 decorator 简化代码书写。
@connect( state => ({todos: state.todos}) disatch => bindActionCreators({todos, dispatch}) ) export default class App extends React.Component{}
在 action 被发起之后,到达 reducer 之前可以使用中间件处理action。
redux-thunk 是处理异步action的redux中间件,它的所有代码如下
redux-thunk
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; }
如果action是函数,那就需要显示调用 dispatch 才能真正触发action,使用方法如下
const getTodo(){ return dispatch => { request.get(url).end((err, res) => { dispatch({ type: 'GET_TODO', data: res.body }) }) } }
应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。惟一改变 state 的办法是触发 action,一个描述发生什么的对象。为了描述 action 如何改变 state 树,你需要编写 reducers。
三大原则
基础
action
Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般使用
store.dispatch()
将action 传到store一个action必须有
type
字段,描述action做的事情,其他字段都为可选项,是action携带的数据,只作为传递数据用途。action 创建函数
Action 创建函数 就是生成 action 的方法。可以简单的理解为调用这个函数就会创建action并且自动调用
store.dispatch()
。当我们使用react-redux
工具时,可以自动绑定dispatch,所以函数可以简化为这样:redux会dispatch函数的返回值
reducer
action 只是描述了有事情发生了这一事实,reducer根据action的描述怎么去更新状态。reducer就是一个纯函数,接收旧的state和action,返回新的state。使用函数默认值设置初始状态。
注意:永远不要在reducer做这些事
不修改state,直接返回一个新对象state
谨记 reducer 一定要保持纯净。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算
拆分 reducer
应用一旦复杂了,reduer会非常长,为了更好的模块化管理,拆分成多个小reducer,然后合并。Redux 提供了 combineReducers() 工具类合并reducer。但只能有一个根reducer,相当于react组件只有一个根标签。
store
action 来描述“发生了什么”,reducers 来根据 action 更新 state 。Store就是把他们联系到一起的对象。Redux 应用只有一个单一的 store
创建store
redux 提供
createStore()
工具创建store,接收根reducer作为参数搭配react
Redux 和 React 之间没有关系。Redux 支持 React、Angular、Ember、jQuery 甚至纯 JavaScript。他只是一个状态管理工具而已。
redux与react搭配使用
react-redux
工具。Provider
将
<Provider />
包围需要使用redux状态的组件。如根组件。provider 需要传递 store 进去。connect && bindActionCreators
在Provider包围的范围内,通过 react-redux 提供的
connect()
方法将包装好的组件连接到Redux。传入组件需要的状态与action 生成函数。bindActionCreators
可以将普通的函数自动绑定变为 action生成函数我们可以使用 es7 的 decorator 简化代码书写。
中间件
在 action 被发起之后,到达 reducer 之前可以使用中间件处理action。
异步action
redux-thunk
是处理异步action的redux中间件,它的所有代码如下如果action是函数,那就需要显示调用 dispatch 才能真正触发action,使用方法如下