Flux
是一個架構,很複雜,適合處理規模較大的東西 (ex. facebook)
要解決的問題:
傳統 MVC,多個 Model 可能會跟多個 View 連結在一起,當資料被改變時,會不知道是誰改變的,所以需要發一個 action 再由 dispatcher 去改變資料,這樣比較可以追蹤資料是由誰改變的
Redux
Redux 要解決的問題:狀態管理(資料、UI 的對應)
用 React 的時候,我們只需要專注於資料,畫面的部分 React 會處理
原理跟 Flux 類似
View -> 觸發 event handler -> dispatch 發了一個 Action -> 到 store 更新狀態 -> 變更 View
這跟 React 的 useReduce 也有點像
React 跟 Redux 是可以分開操作的
Reducer
newState = reducer(currentState, action)
dispatch action -> 傳進去 reducer -> 結合現在的 state -> 合成新的 state
React、Redux 結合
- 安裝 redux
- 安裝 react-redux(新版推薦 Redux Toolkit)
npm install react-redux
資料夾結構
src
/index.js(用來 render app)
- 引入 Provider:讓 Redux store 在 react 可以用
import { Provider } from 'react-redux'; import store from './redux/store'; // 把 store 傳進去,底下就拿得到 store ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById("root") );
redux
/store.js
- 引入 createStore()
redux
/actionTypes.js
- 輸出各個 actionTypes
redux
/actions.js(action creator) - 引入 actionTypes,設定 actionTypes 的 function
redux/reducers
(裡面放各個 reducer 的檔案)
- index.js:引入 combineReducers()、集合各個 reducer 再一起輸出
- todos.js:todos reducer
- users.js:users reducet
App
/App.js(輸出 App)
- 引入 useSelector(hooks),選到想要的東西,對 store 的資料做轉換
- 引入 useDispatch(hooks),拿到 dispatch
Redux DevTool
- chrome 擴充
- 打開 devTool,選擇 redux
- store not found -> 點選連結 -> With Redux -> Basic Store
- 在 store 檔案裡多加上 window 那一段:
const store = createStore( reducer, /* preloadedState, */ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() );
Connect
- 讓 React、redux 結合再一起的一種方法,比起 hooks 版本(useSelector、useDispatch),在專案中比較常用 connect 的版本
- 可以讓 react component 跟 redux 的東西結合在一起
- 是一個 function,用來讀取 Redux store 的 values(如果store 更新,就會重新讀取),傳進兩個參數 mapStateToProps、mapDispatchToProps,可以用來指定你想要拿到的資料
mapStateToProps
:是一個 function, 給你 redux 的 store,會 return 你想要的東西,就會變成 component 的 props(類似 useSelector 的概念)mapDispatchToProps
:可以是一個 function 或一個 object,function: 在 component 被建立時會呼叫一次,dispatch 為參數,會回傳 object,object 裡面是使用 dispatch 來發送 action 的 function;object:裡面是 action creator,每個 action creator 會變成 prop function,並會在呼叫時自動 dispatch action
- 會回傳一個 function
- 資料結構
src/container/AddTodo:跟 redux 關聯的部分
src/component/AddTodo:只負責 UI,不知道 redux 的存在- 好處:好測試,component 的測試歸 component、redux 的測試歸 redux 的
- 不建議 hook 的方法跟 connect 混在一起寫
其他補充
<Fragment></Fragment>
:空的 component,可以簡寫成<></>
- 為什麼我們需要 Redux?
- Redux 是什麼?可以簡介一下 Redux 的各個元件跟資料流嗎?
- 該怎麼把 React 跟 Redux 串起來?