redux和react-redux理解
Posted mikoblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redux和react-redux理解相关的知识,希望对你有一定的参考价值。
最近看到一本书讲解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的实现就比较容易一些了。
以上是关于redux和react-redux理解的主要内容,如果未能解决你的问题,请参考以下文章