最近看到一本书讲解redux和react-redux,又重新学习了一下,写个小小的总结。

一,Redux

  redux只是一种架构模式,它可以应用到任意需要使用它的框架,react,vue等等。它是为了解决相对复杂的应用中不同组件之间共享状态而产生的,比如react中两个组件要访问同一个状态,可以把它提到最近的父组件,然后向下传递,但应用一旦复杂了,这样就会变得繁琐。redux这种模式就解决了类似这样的问题。

redux就是提供了一个叫store的容器里面的state存放了全局的数据状态,对外提供了三个方法getState(), dispatch(), subscribe()

getState(): 用来获取state的值,dispatch(action)用来发起一个action告诉一个叫reducer的函数怎么去更新state,同时把上一次的state作为参数也传给reducer, reducer拿到参数后,返回更新后的state,  得到新的state后就需要渲染组件,可以手动去调用render方法,但这样恒麻烦,通过subscribe接受一个调用render的函数放在一个数组中,每次dispatch的时候除了会通过reducer改变state,还会遍历还数组中的函数去调用,这样每次数据发生变化就可以重新去渲染组件。

跟着书学习手动实现了一个redux:

 1 // redux实现
 2 function createStore(reducer) {
 3   let state = null;
 4   const listeners = [];
 5   const subscribe = (listener) => listeners.push(listener);
 6   const getState = () => state;
 7   const dispatch = (action) => {
 8     //   优化后,stateChanger不再是直接修改state的值,而是返回,用返回的state覆盖原来的state
 9     // stateChanger(state, action);
10     state = reducer(state, action);
11     // 修改dispatch每次调用dispatch的时候,都会调用subscribe传入的监听函数,进行重新渲染,不需手动调用renderApp
12     listeners.forEach(listener => listener());
13   };
14   dispatch({}); // 初始化state
15   return { getState, dispatch, subscribe };
16 }
17 
18 function reducer(state, action) {
19   if (!state) {
20     return {
21       title: {
22         text: '这是标题',
23         color: 'red',
24       },
25       content: {
26         text: '这是内容',
27         color: 'black'
28       }
29     }
30   }
31   switch (action.type) {
32     // 用数据共享的方式返回新的state,{...state}得到的是一个新的对象,复制了state里面所有的属性,
33     // 扩展修改属性,新对象和原对象互相不影响
34     case 'UPDATE_TITLE_TEXT':
35       return {
36         ...state,
37         title: {
38           ...state.title,
39           text: action.text,
40         }
41       }
42     case 'UPDATE_TITLE_COLOR':
43       return {
44         ...state,
45         title: {
46           ...state.title,
47           color: action.color,
48         }
49       }
50     default:
51       return state
52   }
53 }
54 function renderApp (newAppState, oldAppState = {}) {
55     if (newAppState === oldAppState) return // 数据没有变化就不渲染了
56     console.log('render app...')
57     renderTitle(newAppState.title, oldAppState.title);
58     renderContent(newAppState.content, oldAppState.content);
59   }
60   
61   function renderTitle (newTitle, oldTitle = {}) {
62     if (newTitle === oldTitle) return // 数据没有变化就不渲染了  
63     console.log('render title...')
64     const titleDOM = document.getElementById('title')
65     titleDOM.innerHTML = newTitle.text
66     titleDOM.style.color = newTitle.color
67   }
68   
69   function renderContent (newContent, oldContent = {}) {
70     if (newContent === oldContent) return // 数据没有变化就不渲染了
71     console.log('render content...')
72     const contentDOM = document.getElementById('content')
73     contentDOM.innerHTML = newContent.text
74     contentDOM.style.color = newContent.color
75   }
76 
77   const store = createStore(reducer);
78   //   只需调用一次subscribe,后面就不需要重新render
79   let oldState = store.getState(); // 保存旧的状态用以判断
80   store.subscribe(() => {
81     const newState = store.getState();
82     renderApp(newState, oldState);
83     oldState = newState;
84   });
85   renderApp(store.getState());
86   store.dispatch({ type: 'UPDATE_TITLE_TEXT', text: 'miko的小书' });
87   store.dispatch({ type: 'UPDATE_TITLE_COLOR', color: 'gray' });

二,react-redux

      react-redux跟redux不同的是,它是专门为react服务的,它将redux中store的概念和React中context的概念结合起来,解决了相对复杂的react应用中不同组件共享状态传值的问题,它提供一个Provider的容器组件,该组件接收外界通过props将store传给它,并将store放在context中,子组件可以在connect的时候取到store,Connect接收mapStateToProps(该诉高阶组件需要什么样的数据,是一个接收state值作为参数返回所需state对象的函数), mapDispatchToProps(该诉高阶组件怎么样去触发dispatch,是一个函数,接收dispatch作为参数返回包含触发dispatch的函数的对象)作为参数返回一个以当前业务组件作为参数的高阶组件,明白了redux的实现原理,熟悉React,react-redux的实现就比较容易一些了。

posted on 2018-09-05 22:01  mikoLiu  阅读(264)  评论(0编辑  收藏  举报