理解Redux以及如何在項目中的使用


  今天我們來聊聊Redux,這篇文章是一個進階的文章,建議大家先對redux的基礎有一定的了解,在這里給大家推薦一下阮一峰老師的文章: http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html       

   對於基礎部分我在這里稍微講解一下

  首先我們要知道我們為什么要使用Redux,我們在什么情況下才需要去使用Redux,在這里引用Redux的創造者的一句話:"只有遇到 React 實在解決不了的問題,你才需要 Redux 。" 

  結合項目經驗說下我自己的理解:如果這批數據只是在一個組件使用並且不需要和別的組件進行數據共享,從單一來源獲取數據的時候,也就是說你的UI層很簡單,沒有復雜的數據流動,總之就是加入數據流動單項並且很簡易,沒有與服務器的大量交互的情況下,我們不需要使用Redux,否則只會讓我們的開發變得更加復雜。

  那么什么時候我們需要用到Redux呢:比如你的數據流動很復雜,這批數據有多個組件需要使用甚至別的頁面也需要使用它,或者說就是你的某些狀態需要在多個沒有強關聯的組件中用到,舉個很常見的例子,就比如說我們做登錄保存用戶信息或者是做購物車的時候,我們就很有必要引入Redux來幫我們做狀態管理了,總之,就是在你某些狀態或者數據的很難控制很難傳遞的時候,你需要Redux來幫助你。

   參照這張經典圖來講解一下Redux的工作原理

                                                                           

 

  組件Component通過ActionCreators派發一個行為action(注意在這里是派發一個扁平對象),這個行為被派發到了Store,Store借助Reducer確認該State的狀態並執行相應的操作,接下來Reducer把新的State返回給Store,最后Store把這個State轉給了Component。

 

   假如說你已經在你使用Redux做過一些小demo了,我講一下在項目中的一個Redux進階用法,我就根據上面講的Redux的工作流程,結合偽代碼給大家講解一下在項目中我們應該如何去使用它(建議把這段偽代碼通讀幾遍,因為本人寫的前后順序排的不是很合理,但是通讀下來幾遍的話,相信你能理解的):

  第一步:我們要在最外面注冊一個Store

import { createStore, applyMiddleware } from 'redux'    //applyMiddleware作用是提供一個中間件,關於Redux中中間件的理解大家可以去官網看一下,很有用處,鏈接地址:http://cn.redux.js.org/docs/advanced/Middleware.html
import thunk from 'redux-thunk' //可以讓dispatch傳的內容就不會局限於只能傳一個扁平對象了,就可以傳一個函數了,關於redux-thunk的話后期我給大家寫一個它源碼的解析,最近太累了,感興趣的伙伴先自己查查
import reducers from './reducers'   const store = createStore(reducers,applyMiddleware(thunk))    export default store

 

  第二步:可能你會有很多個地方要用到Redux,那么你可能會有很多reducer,這個時候我們會需要redux提供的combineReducers來將我們各個地方的reducer進行合並,就會讓它們互不影響

import { combineReducers } from 'redux' //為了可以引入多個reducer

//以下是偽代碼,只是模擬我們有多個reducer,我們可以把它們合並起來,互不影響
import {reducer as first} from 'pages/first' import {reducer as ticket} from 'pages/ticket' export default combineReducers({ first, ticket })

  第三步:全局注入store

import { Provider } from 'react-redux'    //你可以Provider想象成一個注入器,它可以幫我們把store注入到我們的根組件上,這樣的話store將無處不在 import store from './store' ReactDOM.render( <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root') )

  接下來就是我們某個地方要如何使用Redux,假設現在的場景是這樣的,我們要派發一個action,同時這個action還要去請求ajax,ajax又是異步的,這個時候我們剛才的那個thunk就有作用了,我先簡單講解一下它的作用,我們通常情況下是提交一個扁平對象,然后這個action直接送到reducer中去進行操作,但是我們有異步請求數據的時候怎么辦呢,thunk給我們提供的就是我們派發行為的時候可以派發一個函數,再派發一個扁平對象,當遇到函數的時候會先執行函數里面的內容最后再去提交到reducer中,好,大概你應該懂我的意思了,開始操作:

 

       第四步:我們要觸發action對吧,為了避免命名沖突,我們先來創建一個actionTypes.js文件,我們要給每個type加一個命名空間:

export const GET_COMMENT_DATA = 'ticket/get_comment_data' export const SET_RECORD_DATA = 'ticket/set_record_data'

 

  

  第五步:我們要去派發一個action,直接把怎么拿store中的數據也寫出來把

const mapDispatch = (dispatch)=>{ return { loadList(){ dispatch(loadListDataAsync(dispatch)) } } }
const mapState = (state) => { return { swiperList: state.first.list } }

 

   

  第六步:我們要從react-redux中引入一個connect,它是幫助我們來可以在組件中使用dispatch和state的,寫法是這樣的:

export default connect(mapState,mapDispatch)(App)
記錄下我之前遇到的一個小坑,之前我是只在當前組件中用到了dispatch,所以我是這樣寫的:
export default connect(mapDispatch)(App)      //后來發現會有一堆紅色的怪物包圍着我
正確的姿勢其實是這樣的:
export default connect(null,mapDispatch)(App)

 

   

  第七步:我們去看看我們是怎么利用thunk請求ajax數據的把:

import { GET_COMMENT_DATA } from './actionTypes' export const LoadCommentDataAsync = (dispatch,id)=>{         return ()=>{              //在這個函數中我們可以進行異步請求數據 fetch('/haha', { method: 'GET', headers: { 'content-type': 'application/json' }, }) .then(response => response.json()) .then(result=>{ dispatch({            //遇到扁平對象了,可以提交到reducer了 type: GET_COMMENT_DATA, comments: result }) }) } }

 

   

  第八步:我們來到reducer中處理你的action

import { GET_COMMENT_DATA } from './actionTypes' import { SET_RECORD_DATA } from './actionTypes' const defaultState = { comments: {}, records: [] } export default (state=defaultState,action)=>{ if(action.type === GET_COMMENT_DATA){ return { ...state, comments: action.comments } } if(action.type === SET_RECORD_DATA){ return { ...state, records: [...state.records,action.records] } } return state }

 

  

  第九步:我們把這個reducer暴露出來,也就是我們第一步在reducers中引入的reducer

import reducer from './reducer' export { reducer }

 

 

 

    這篇寫的不是很好,原諒我,最近很多事都堆在一起了,等我調整好了,這次的代碼就當成全是偽代碼來看,重在理解Redux的流程以及它是如何在項目中進行使用的,理解它的用法即可,相信你看懂了以后在寫項目的時候會對它的理解會越來越深刻的,別看我代碼是怎么寫的,就看看步驟就行了,我承認這次寫的很爛(:,等我調整好了給大家把注釋和解釋再完善完善,后期我會來修改它的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM