การ Setup Redux และใช้งาน เป็นอะไรที่ค่อนข้างเหนื่อย และซับซ้อน เนื่องจากขั้นตอนเยอะ แถมเวลาใช้งานมันเพิ่มความซับซ้อนให้กับ Code ของเราประมาณนึงเลย
ทีมพัฒนา Redux เลยคิด Tool ขึ้นมาช่วยในการ Setup และใช้งานที่มีชื่อว่า Redux Toolkit
Redux Toolkit เกิดมาขึ้นเพื่อทำให้เรา Setup และใช้งาน Redux ได้ง่ายมากยิ่งขึ้น
🌟 ทีมพัฒนา Redux แนะนำการใช้ Redux Toolkit กับ Production App
เราจะ Install package redux toolkit npm install @reduxjs/toolkit react-redux
จากนั้นเราจะเริ่ม Setup Redux
1. สร้าง Redux Store ก่อน
- ให้สร้างไฟล์ไว้ที่ที่
app/store.js
- Store ของ redux-toolkit สามารถใช้ redux-thunk และ redux devtools extension ได้เราไม่ต้องไป setup เพิ่มเอง
import { configureStore } from "@reduxjs/toolkit";
export default configureStore({
reducer: {},
});
2. เชื่อมต่อ Store เข้าไปใน React App ที่ src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import store from "./app/store";
import { Provider } from "react-redux";
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
3. สร้าง Redux State Slice
- Redux State Slice เป็นตัวที่จะรับ actions เข้ามาแล้วทำการ update app states ตาม actions ที่เข้ามา
import { createSlice } from "@reduxjs/toolkit";
export const counterSlice = createSlice({
name: "counter",
initialState: {
counter: 0,
},
reducers: {
increment: (state) => {
state.counter += 1;
},
decrement: (state) => {
state.counter -= 1;
},
reset: (state) => {
state.counter += 0;
},
},
});
export const { increment, decrement, reset } = counterSlice.actions;
export default counterSlice.reducer;
4. เพิ่ม Slice Reducers เข้าไปใน Store
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
export default configureStore({
reducer: {
counter: counterReducer,
},
});
5. เรามาลองใช้ State และ Dispatch Action ใน Component กัน
function CounterPage() {
const counter = useSelector((state) => state.counter.counter);
const dispatch = useDispatch();
const [toggle, setToggle] = useState(true);
const history = useHistory();
return (
<div>
<h1>Counter page</h1>
{toggle && (
<Counter
counter={counter}
addCounter={() => dispatch(increment())}
subtractCounter={() => dispatch(decrement())}
resetCounter={() => dispatch(reset())}
/>
)}
<h1>Show Counter: {counter}</h1>
<button onClick={() => setToggle(!toggle)}>Toggle</button>
<button onClick={() => history.push("/")}>Back To Home</button>
</div>
);
}
- เราสามารถที่จะส่งข้อมูลไปกับ Action ได้ เราจะเพิ่ม function ให้กับ counter app ที่มีชื่อว่า
addByAmount
<Counter
counter={counter}
addCounter={() => dispatch(increment())}
subtractCounter={() => dispatch(decrement())}
resetCounter={() => dispatch(reset())}
addByAmount={() => dispatch(addByAmount(10))}
/>
ใน component counter เราจะเพิ่มปุ่ม add by amount เข้าไป
import {
decrement,
increment,
reset,
addByAmount,
} from "../feature/counter/counterSlice";
// Skipped code
<div>
<h1>{props.counter}</h1>
<button onClick={props.addCounter}>add</button>
<button onClick={props.subtractCounter}>subtract</button>
<button onClick={props.resetCounter}>reset</button>
<button onClick={props.addByAmount}>add by amount</button>
</div>;
ในตัว counterSlice เราจะเพิ่ม incrementByAmount action เข้าไป ใน reducers key
export const counterSlice = createSlice({
name: "counter",
initialState: {
counter: 0,
},
reducers: {
// Skipped Code
addByAmount: (state, action) => {
state.counter += action.payload;
},
},
});
export const {
increment,
decrement,
reset,
addByAmount,
} = counterSlice.actions;
Redux ทำให้เราสามารถที่จะบอกได้ว่า States ใน App ของเรานั้นเปลี่ยนแปลงได้อย่างไร ที่ไหน เมื่อไหร่ และทำไม ซึ่ง Redux จะมี Tool ที่ชื่อว่า Redux DevTools