We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
最近這陣子最夯的前端技術應該就是redux了 趁著比較有空的時候,看了一堆文件跟教學,算是對redux有了一點小小心得 在這邊幫自己做個筆記,也試著用自己的話解釋一下這個東西 話說其實官方文件我覺得寫得不錯,而且中文翻譯版也不錯,很多東西都講得深入淺出,很推薦去看一下
redux
適合閱讀這篇文章的人:
不適合閱讀這篇文章的人:
flux裡面有幾個重要的概念:action、action creator、dispatcher、store、view
action
action creator
dispatcher
store
view
先從action開始,我們知道在flux的架構裡面,action是唯一可以改變store裡面的數據的方法 redux跟flux在這方面比較不一樣的點是, flux是經由Action creator直接建立action並且dispatch出去,像是
flux
Action creator
dispatch
var addItem = function(item) { Dispatcher.dispatch({ type: ActionTypes.ADD_ITEM, item: item }); } ActionCreator.addItem(..);
但是在redux裡面,ActionCreator只會產生一個純粹的javascript object 你要自己dispatch出去
ActionCreator
function addTodo(text) { return { type: ADD_TODO, text }; } store.dispatch(addTodo(text));
而且跟flux的差別是,dispatch這個動作是用store來達成 把原本的Dispatcher這個東西拿掉了
Dispatcher
再來,redux裡面只有一個store 這一點也跟flux滿不一樣的,那這時候可能會有疑問說:只有一個store,把所有資料都放在這邊,不會很雜亂嗎? 接著就要引入一個redux裡面很重要的概念:reduce
reduce
什麼是reduce?其實很簡單,就是(previousState, action) => newState 給你現在的狀態跟要執行的動作,傳回一個新的狀態 例如說我們現在要新增一個todo的item
(previousState, action) => newState
function addTodos(state, action) { return [...state, { text: action.text, completed: false }]; }
之前的狀態->新增一筆資料->新的狀態 這就像是一個狀態機,只要保證input跟action一樣,就能保證輸出的結果永遠都一樣 例如f(1)=1的話,永遠不會出現f(1)=2的情形 給一個狀態跟操作->改變資料->傳回新的狀態
而在這邊值得注意點的是,為什麼不寫成
function addTodos(state, action) { return state.push({ text: action.text, completed: false }) }
這是之前React有提過的概念:Immutable State 就是說store裡面的數據,是不可改變的,你不能直接對它做編輯 你能做的就只有把整個state都換掉 為什麼要這樣做? 這跟React有一點關係,還記得一個很重要的概念嗎?always re-render 但其實如果數據沒有改變的話,根本就不需要重新render React裡面有一個function是shouldComponentUpdate 你可以直接寫成:
React
shouldComponentUpdate
shouldComponentUpdate: function(nextProps, nextState) { return this.props !== nextProps; }
如果上個狀態跟現在的狀態不相等的話,才需要update
先假設我們的state現在是可以編輯的,來看看會發生什麼事
var prevState = {name:"yo"} var newState = prevState; newState.name = "new" prevState===newState //true
在這個情形底下,因為===只會比較這兩個變數所指向的記憶體位置是否一樣,所以回傳了true 所以每當我們要改變state的時候,就要重新new一份
===
true
var prevState = {name:"yo"} var newState = {name:"new"}; prevState===newState //false
以上是只有一筆資料的簡單情形,如果資料很多怎麼辦? 每次都重新new一份不是很浪費空間嗎? 所以可以採用一種更好的做法,對於沒有變動的地方,就直接使用;有變動的地方再new一份 應該會長得有點像這樣
var prevState = { todos: [1,2,3], name: "peter" } var newState = { todos: prevState.todos, name: "new" } prevState.todos===newState.todos//true prevState==newState //false
那我們在實做的時候,有幾種方法可以選擇
但其實不可改變的state這個概念只是推薦用法,你不這樣用,想要改變它也是可以 只是可能有些很酷的功能沒有辦法使用而已
還記得store裡面儲存了整個app的state,然後會切割不同部分,交給不同的reducer去處理,最後再統一結果 所以結構上面還是相當良好的 大家可以直接看官方文檔裡面的這段code
reducer
function todos(state = [], action) { switch (action.type) { case ADD_TODO: return [...state, { text: action.text, completed: false }]; case COMPLETE_TODO: return [ ...state.slice(0, action.index), Object.assign({}, state[action.index], { completed: true }), ...state.slice(action.index + 1) ]; default: return state; } } function visibilityFilter(state = SHOW_ALL, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return action.filter; default: return state; } } function todoApp(state = {}, action) { return { visibilityFilter: visibilityFilter(state.visibilityFilter, action), todos: todos(state.todos, action) }; }
todoApp就是整個store,然後切割成visibilityFilter跟todos兩個reducer 分別對自己所關心的state做出反應,回傳新的state 這份code用了大量的ES6,所以看redux的好處就是還可以順便學習ES6
todoApp
visibilityFilter
todos
其實redux的一些特性到這邊講得差不多了 就跟flux滿像的,就action creator -> 發action -> store接到action -> 分配給reducer -> 產生新的state view那邊就subscribe state的變化,這點跟之前flux一樣 接著要講一個redux比較不一樣的點
有接觸過express的人相信對middleware不會太陌生,在redux裡面的middleware指的是 從action到store的這段路程當中,可以經過很多middleware action -> middleware1 -> middleware2 -> store 這樣的好處是什麼呢?
express
redux在middleware裡面非同步API的實作我沒有看得很懂,不過大概可以講一下概念 原本的action是指一個Plain Javascript Object,就是長得像這個樣子
{ type: "ADD_TODO" }
那現在如果action變成一個function呢? 就可以寫一個專門處理function的middleware 只要碰到是function,就立刻執行 那假如今天這個function是一個去遠端拿資料的操作
//action creator function receiveResult(result){ return { type: "RECEIVE_RESULT", result: result } } function get(){ return function(){ API.get(function(result){ store.dispatch(receiveResult(result)); } } } store.dispatch(getSomething());
middleware在處理到的時候,就會執行這個function,而function執行完會dispatch一個action 詳細的說明可以看我最下面附的參考資料,或是直接參考官方文件 因為官方文件真的寫得很不錯
原本在flux的架構裡面,沒有很明確指定說怎麼做非同步的api呼叫 但是在redux給了我們明確解答: 就是發action
最後稍微提一下怎麼跟React做結合 redux提供了Provider,讓你把store注入到你的react元件裡面去 所以在root的地方必須這樣做
Provider
let store = createStore(todoApp); let rootElement = document.getElementById('root'); React.render( <Provider store={store}> {() => <App />} </Provider>, rootElement );
在個別元件的地方,用connect這個指定這個元件要接收哪些state 如果沒有指定的話,就會接收到整個store的state,也就是這整個應用程式的state
connect
在看redux的時候,只要有flux的基礎,就會發現兩者有滿多地方類似 而redux簡化了一些步驟,引進一些flux原本沒有的東西,但是核心思想還是差不多的,就是「單向資料流」 redux的sample code也很棒,分成幾個範例,一個叫做real world的範例最完整 裡面應用了react-router與github api,實際示範如何與這些東西做搭配 只要能熟悉這個範例,相信採用redux來開發SPA會還滿得心應手的
real world
react-router
github api
最後,再次推薦官方文件 下面列出我在寫這篇文之前看過的一些文章,有興趣的可以看看
ref: Redux 初步尝试 还在纠结 Flux 或 Relay,或许 Redux 更适合你 Redux basic tutorial Redux 中文文档 redux-promise redux-tutorial Redux 核心概念 Thunk 函数的含义和用法 Functional JavaScript Mini Book Redux 入門 The React.js Way: Flux Architecture with Immutable.js react - Advanced Performance gaearon/normalizr
The text was updated successfully, but these errors were encountered:
No branches or pull requests
最近這陣子最夯的前端技術應該就是redux了
趁著比較有空的時候,看了一堆文件跟教學,算是對
redux
有了一點小小心得在這邊幫自己做個筆記,也試著用自己的話解釋一下這個東西
話說其實官方文件我覺得寫得不錯,而且中文翻譯版也不錯,很多東西都講得深入淺出,很推薦去看一下
適合閱讀這篇文章的人:
不適合閱讀這篇文章的人:
既然你已經懂flux了,就直接切入正題吧!
flux裡面有幾個重要的概念:
action
、action creator
、dispatcher
、store
、view
Action
先從action開始,我們知道在
flux
的架構裡面,action
是唯一可以改變store
裡面的數據的方法redux
跟flux
在這方面比較不一樣的點是,flux
是經由Action creator
直接建立action
並且dispatch
出去,像是但是在
redux
裡面,ActionCreator
只會產生一個純粹的javascript object你要自己dispatch出去
而且跟
flux
的差別是,dispatch這個動作是用store
來達成把原本的
Dispatcher
這個東西拿掉了再來,
redux
裡面只有一個store這一點也跟
flux
滿不一樣的,那這時候可能會有疑問說:只有一個store,把所有資料都放在這邊,不會很雜亂嗎?接著就要引入一個
redux
裡面很重要的概念:reduce
reduce
什麼是
reduce
?其實很簡單,就是(previousState, action) => newState
給你現在的狀態跟要執行的動作,傳回一個新的狀態
例如說我們現在要新增一個todo的item
之前的狀態->新增一筆資料->新的狀態
這就像是一個狀態機,只要保證input跟action一樣,就能保證輸出的結果永遠都一樣
例如f(1)=1的話,永遠不會出現f(1)=2的情形
給一個狀態跟操作->改變資料->傳回新的狀態
而在這邊值得注意點的是,為什麼不寫成
Immutable State
這是之前
React
有提過的概念:Immutable State就是說store裡面的數據,是不可改變的,你不能直接對它做編輯
你能做的就只有把整個state都換掉
為什麼要這樣做?
這跟
React
有一點關係,還記得一個很重要的概念嗎?always re-render但其實如果數據沒有改變的話,根本就不需要重新render
React
裡面有一個function是shouldComponentUpdate
你可以直接寫成:
如果上個狀態跟現在的狀態不相等的話,才需要update
先假設我們的state現在是可以編輯的,來看看會發生什麼事
在這個情形底下,因為
===
只會比較這兩個變數所指向的記憶體位置是否一樣,所以回傳了true
所以每當我們要改變state的時候,就要重新new一份
以上是只有一筆資料的簡單情形,如果資料很多怎麼辦?
每次都重新new一份不是很浪費空間嗎?
所以可以採用一種更好的做法,對於沒有變動的地方,就直接使用;有變動的地方再new一份
應該會長得有點像這樣
那我們在實做的時候,有幾種方法可以選擇
但其實不可改變的state這個概念只是推薦用法,你不這樣用,想要改變它也是可以
只是可能有些很酷的功能沒有辦法使用而已
再回到reducer
還記得store裡面儲存了整個app的state,然後會切割不同部分,交給不同的
reducer
去處理,最後再統一結果所以結構上面還是相當良好的
大家可以直接看官方文檔裡面的這段code
todoApp
就是整個store,然後切割成visibilityFilter
跟todos
兩個reducer分別對自己所關心的state做出反應,回傳新的state
這份code用了大量的ES6,所以看redux的好處就是還可以順便學習ES6
其實redux的一些特性到這邊講得差不多了
就跟flux滿像的,就action creator -> 發action -> store接到action -> 分配給reducer -> 產生新的state
view那邊就subscribe state的變化,這點跟之前flux一樣
接著要講一個redux比較不一樣的點
Middleware
有接觸過
express
的人相信對middleware不會太陌生,在redux
裡面的middleware指的是從action到store的這段路程當中,可以經過很多middleware
action -> middleware1 -> middleware2 -> store
這樣的好處是什麼呢?
redux在middleware裡面非同步API的實作我沒有看得很懂,不過大概可以講一下概念
原本的action是指一個Plain Javascript Object,就是長得像這個樣子
那現在如果action變成一個function呢?
就可以寫一個專門處理function的middleware
只要碰到是function,就立刻執行
那假如今天這個function是一個去遠端拿資料的操作
middleware在處理到的時候,就會執行這個function,而function執行完會dispatch一個action
詳細的說明可以看我最下面附的參考資料,或是直接參考官方文件
因為官方文件真的寫得很不錯
原本在
flux
的架構裡面,沒有很明確指定說怎麼做非同步的api呼叫但是在
redux
給了我們明確解答: 就是發action與React的結合
最後稍微提一下怎麼跟React做結合
redux
提供了Provider
,讓你把store
注入到你的react元件裡面去所以在root的地方必須這樣做
在個別元件的地方,用
connect
這個指定這個元件要接收哪些state如果沒有指定的話,就會接收到整個store的state,也就是這整個應用程式的state
在看
redux
的時候,只要有flux
的基礎,就會發現兩者有滿多地方類似而
redux
簡化了一些步驟,引進一些flux
原本沒有的東西,但是核心思想還是差不多的,就是「單向資料流」redux
的sample code也很棒,分成幾個範例,一個叫做real world
的範例最完整裡面應用了
react-router
與github api
,實際示範如何與這些東西做搭配只要能熟悉這個範例,相信採用
redux
來開發SPA會還滿得心應手的最後,再次推薦官方文件
下面列出我在寫這篇文之前看過的一些文章,有興趣的可以看看
ref:
Redux 初步尝试
还在纠结 Flux 或 Relay,或许 Redux 更适合你
Redux basic tutorial
Redux 中文文档
redux-promise
redux-tutorial
Redux 核心概念
Thunk 函数的含义和用法
Functional JavaScript Mini Book
Redux 入門
The React.js Way: Flux Architecture with Immutable.js
react - Advanced Performance
gaearon/normalizr
The text was updated successfully, but these errors were encountered: