React Redux简单实现
设计思想1.web应用是一个状态机,试图与状态是一一对应的. 基本改变和API1.Store import { createStore } from 'redux'; const store = createStore(reducer); createStore函数接受另一个reducer函数作为参数,返回新生成的Store对象. 2.State const state = store.getState(); 3.Action const action = { type: 'ADD_TODO',payload: 'learn Redux' }; Action的名称是ADD_TODO,它携带的信息是字符串Learn Redux. 4.Action Creator const ADD_TODO = '添加 TODO'; function addToDo(text) { return { type: ADD_TODO,text } } 5.store.dispatch() store.dispatch(addTODO('Learn Redux')); 6.reducer export default (state = 0,action) => { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; case 'getSource': return 'bbbb'; default: return 0; } } reducer函数收到名为ADD的action以后,就返回一个新的state,作为加法的计算结果,其他计算的逻辑, const store = createStore(reducer); createStore接受Reducer作为参数,生成一个新的Store.以后每当store.dispatch发送过来一个新的Action, return Object.assign({},state,{ thingToChange }) export default (state = 0,action) => { switch (action.type) { case 'INCREMENT': return state + 1; case 'DECREMENT': return state - 1; case 'getSource': return 'bbbb'; case 'ajax': return action.data; case 'ajaxError': return action.data default: return 0; } } 8.store.subscribe() store.subscribe(listener); 显然,只要把view的更新函数(render或this.setState)放入listen,就会实现view的自动渲染. Store的实现1.store.getState(),store.dispatch(),store.subscribe() let { subscribe,dispatch,getState } = createStore(reducer); Reducer的拆分Reducer函数负责生成State,由于整个应用只有一个state对象,包含所有数据,对于大型应用来说,这个State import { combineReducers } from 'redux'; const chatReducer = combineReducers({ chatLog,statusMessage,userName }) 工作流程1.用户发出Action store.dispatch(action); 2.Store自动调用Reducer,并且传入两个参数,当前State和收到的Action.Reducer会返回新的State. let nextState = todoApp(previousState,action); 3.State一旦有变化,Store就会调用监听函数. store.subscribe(listener); 4.listener可以通过store.getState()得到当前状态,如果使用的是React,这时可以触发重新渲染view. function listerner() { let newState = store.getState(); component.setState(newState); } 实例import React,{ Component } from 'react'; import { render } from 'react-dom'; import reducer from '../reducers/reducer.js'; import { createStore } from 'redux'; const store = createStore(reducer); class App extends Component { constructor(props) { super(props); this.state = { count: 0,source: 'aaaa',ajaxSource: 'ajax' }; } handleAdd = () => { store.dispatch({ type: 'INCREMENT' }); } handleDel = () => { store.dispatch({ type: 'DECREMENT' }); } handleGet = () => { store.dispatch({ type: 'getSource' }) } handleAjax = () => { fetch('../api/response.json') .then(response => response.json()) .then((res) => { store.dispatch({ type: 'ajax',data: res }); }).catch((err) => { store.dispatch({ type: 'ajaxError',data: err }); }) } render() { let _this = this; store.subscribe(() => { let o = store.getState(); _this.setState({ [o.type]: store.getState()[o.type] }) }); return ( <div> <span>{ this.state.count }</span> <button onClick={ this.handleAdd }>add</button> <button onClick={ this.handleDel }>del</button> <span>{ this.state.source }</span> <button onClick={ this.handleGet }>获取数据</button> <span>{ this.state.ajaxSource.res }</span> <button onClick={ this.handleAjax }>获取ajax数据</button> </div> ); } } render(<App />,document.getElementById('root')); export default (state = 0,action) => { switch (action.type) { case 'INCREMENT': return Object.assign({},{ count: state + 1,type: 'count' }); case 'DECREMENT': return Object.assign({},{ count: state - 1,type: 'count' }); case 'getSource': return Object.assign({},{ source: action.dada,type: 'source' }); case 'ajax': return Object.assign({},{ ajaxSource: action.data,type: 'ajaxSource' }) case 'ajaxError': return Object.assign({},type: 'ajaxSource' }); default: return state } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |