# Redux Redux 是一個狀態處理的工具,這並不是 react 特有的,可以將 Redux 應用在任何 js 專案。 Redux 可以想像成是一個大型的狀態管理中心,注意就是只有一個,Redux 會包含一個 reducer ,用來管理各種 action 應該執行的功能,並且可以有一個 subscriber,用來指定 state 出現變化時的行為。 Redux 在 react 中可以透過 useContext + useReducer 達到類似的效果。 使用 Redux 在 react 前,先進行以下操作: ``` npm install redux react-redux ``` Redux 簡單的用法: ```jsx const counterReducer = (state = {counter: 0}, action) => { if (action.type === 'increment') { return { counter: state.counter + 1 } } if(action.type === 'decrement') { return { counter: state.counter - 1 } } return state; }; const store = createStore(counterReducer); export default store; ``` :::warning 注意要 return state ::: 把這個檔案 import 進要使用 redux 的元件 (通常在最上層): ```jsx import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import {store} from "./store/index" import { Provider } from 'react-redux'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<Provider store={store}><App /> </Provider>); ``` ## 使用 state 當其他 component 要使用時,可使用以下語法: ```jsx const counter = useSelector(state => state.counter); ``` 代表從 redux 中抓取這個 state,之後就可以把這個 counter 拿來使用。 :::success 使用 useSelector 抓取這個 state 的話,當這個 state 被更新時也會自動刷新(就像普通的 useState)。 ::: ## dispatch 使用 useDispatch 抓取 dispatch 的函式 ```jsx const disPatch = useDispatch(); ``` 接下來就像 useReducer 一樣,使用 dispatch function 傳入 action: ```jsx function handleIncrement(){ disPatch({type: "increment"}); } function handleDecrement(){ disPatch({type: "decrement"}); } ``` ## redux-toolkit 很明顯的,如果我們這樣把每一個 state 集中管理在一個檔案,又用這麼簡單的 if-else 來處理,當專案變大馬上就會變得無法管理,因此有了 redux-toolkit 套件,使用前,透過命令安裝: ``` npm install @reduxjs/toolkit ``` 接下來找到用來管理各個 state 的檔案,假如跟前面一樣要管理一個 counter: ```jsx const initialState = { counter: 0} const counterSlice = createSlice({ name: "counter", initialState: initialState, reducers: { increment(state) { state++; }, decrement(state) { state--; }, } }); ``` name 是這個 slice 的名字,其他就是初始值和 reducer。 :::danger 照理說,不應該這樣直接修改 state 的內容,但因為在 redux-toolkit 中有特殊內建工具,當使用這種語法時會被轉換成合法的語法 ::: 接下來就可以透過這個函式把 state 匯出使用 ```jsx const store = configureStore({ reducer: {counter: counterSlice.reducer} }); export const conterAction = counterSlice; export default store; ``` :::info 記得也要 export counterAction! ::: 匯出的這個 action 可以讓其他的 component 可以輕鬆指定要使用的函式。 當其他 component 要使用這個 slice 時,可以透過: ```jsx function handleIncrement(){ disPatch(counterAction.increment); } function handleDecrement(){ disPatch(counterAction.increment); } ``` 來完成,redux-toolkit 會自動把這個語法轉換成前面提到的 reducer 中的那些 if-else,讓整個 state 變得更容易管理。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up