iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
自我挑戰組

用ChatGPT詠唱來完成工作與點亮前後端技能樹系列 第 23

【Day23】ChatGPT請教教我:React進階(一)- React Redux 狀態管理

  • 分享至 

  • xImage
  •  

目前這個系列已挑選ChatGPT、前端&React相關章節出版成書!
感謝大家的閱讀與支持!
《用 ChatGPT 詠唱來點亮 React & 前端技能樹》
歷經重新整理、校正、編排、與修改後,讓章節內容之間的銜接更平順,除了補充上更多的解說之外,甚至有部分章節為重新撰寫的內容,讓理解變得更輕鬆!
目前已在天瓏書局博客來金石堂等通路都買得到了! 也有電子書的選擇!
歡迎各位點擊連結選購,謝謝大家~
https://ithelp.ithome.com.tw/upload/images/20240419/20135750lQM12by6v1.jpg


在Day16的時候,介紹了useState這個管理、更改狀態的hook
透過 count [count, setCount] = useState<number>(0) 的語法
讓我們拿到 count這個狀態變數,以及setCount 這個更改狀態的function

在複雜的專案中,單用useState 可能還是會造成管理混亂
setCount 的使用方式並沒有限制,在更改state的時候邏輯比較鬆散
可以隨意的 setCount(count+2)或是 setCount(count*2)

在大型且複雜專案的管理狀態上,還有另外一個工具可以更嚴謹的幫助我們在React中管理state
——React Redux

這個章節讓ChatGPT介紹什麼是 react redux
運作流程和方式又是什麼,GO GO

React Redux

https://ithelp.ithome.com.tw/upload/images/20231005/20135750vynbmNVHcE.png

嗨!當然可以,讓我來為你介紹一下 React Redux。

首先,React Redux 是一個用於管理 React 應用程式狀態的庫。它結合了 React 和 Redux,這兩者可以讓你更有效地管理你的應用程式狀態。

接下來,讓我來講解一些 Redux 的基礎觀念:

  1. 單一資料來源 (Single Source of Truth)
    Redux 的核心理念是將整個應用程式的狀態保存在一個稱為 "Store" 的物件中。這個 Store 是應用程式的單一資料來源,這表示所有的狀態都會以一個物件樹的形式存放在這個 Store 中。
  2. 狀態是唯讀的 (State is Read-Only)
    在 Redux 中,狀態是唯讀的,這表示你無法直接修改狀態。如果你想要改變應用程式的狀態,你必須派發一個 "Action"。
  3. 使用純粹函數 (Changes are made with pure functions)
    為了改變應用程式的狀態,你需要編寫一個稱為 "Reducer" 的純粹函數。Reducer 接收一個當前狀態和一個 Action,並回傳一個新的狀態。
  4. 單向數據流 (Unidirectional Data Flow)
    Redux 強調了單向數據流的概念,這表示資料的流動是單向的,從 Store 到 View,然後是從 View 到 Action。
  5. 使用Action來描述事件 (Actions describe events)
    Action 是一個用來描述發生了什麼事件的物件。它會携帶一些基本資訊,例如事件類型 (type) 和相關的資料。

總的來說,Redux 提供了一個有效的方法來管理應用程式的狀態,特別是在大型或複雜的應用程式中。透過將狀態統一儲存在一個 Store 中,並使用 Actions 和 Reducers 來管理狀態的改變,我們可以保持應用程式的可預測性和可維護性。

希望這份簡介對你有所幫助!如果你有任何其他問題或需要更多解釋,請隨時告訴我。

講了一些觀念,提到了「Store」、「Actions」、「Reducers」
但可能還是太過抽象了,相當的咬文嚼字
讓ChatGPT用比較好懂的比喻來講述流程看看
https://ithelp.ithome.com.tw/upload/images/20231005/20135750RcsE8LDzcV.png

當然!我用一個生活中的比喻來解釋 Redux 的運作流程:

想像你在玩一個角色扮演遊戲,你的角色身上有很多屬性,比如生命值、魔法值等等。這些屬性都存在於一個特別的袋子裡,稱為「屬性袋」。

  1. Store (屬性袋):
    • 在 Redux 中,我們有一個特別的袋子叫做「Store」,裡面存放著所有的應用程式狀態,就像是你角色的所有屬性都在這個屬性袋裡。
  2. Action (命令):
    • 當你想改變你角色的某個屬性,比如增加生命值,你會發出一個特定的指令,比如「加生命值」。
  3. Reducer (處理器):
    • 這個指令會傳給一個處理器,就像是一個會根據你的指令執行特定動作的魔法師。這個魔法師會根據指令,把你的角色的生命值加上指定的數量。
  4. 新的狀態 (更新後的屬性袋):
    • 處理器完成工作後,會給你一個更新後的屬性袋,裡面的屬性已經被修改過了。

這樣就完成了一個簡單的 Redux 流程:

  1. 你想要改變某個狀態,就像是想要增加生命值。
  2. 你發出一個特定的指令(Action),比如「加生命值」。
  3. 這個指令被傳給處理器(Reducer)。
  4. 處理器根據指令,修改狀態,然後給你一個更新後的狀態(屬性袋)。

這樣,Redux 就像是一個角色扮演遊戲中的魔法師,幫助你管理角色的屬性。希望這個比喻能讓你更容易理解 Redux 的運作流程!如果你有任何問題,隨時告訴我。

雖然用詞很奇怪,但勉勉強強,列舉各項名詞和比喻之後好一點…點…

還…還是看不懂就畫圖!
https://ithelp.ithome.com.tw/upload/images/20231005/20135750zitDTCR24h.png

當然,我可以用 Mermaid 語法來表示 Redux 的運作流程。以下是一個簡單的 Mermaid 流程圖,說明 Redux 的基本流程:

graph TD
  A[Action] -->|觸發| B[Reducer]
  B --> C[Store]
  C -->|更新| D[View]
  D -->|互動| A

在這個流程圖中,我們有以下幾個元素:

  • Action (行動):代表應用程式中的某個事件,它可以觸發狀態的改變。
  • Reducer (處理器):處理 Action,並根據 Action 的類型來修改應用程式的狀態。
  • Store (儲存庫):存放整個應用程式的狀態,是所有狀態的「單一來源」。
  • View (視圖):展示應用程式的介面,當狀態改變時,會更新並顯示新的資料。

流程如下:

  1. 一個 Action 被觸發,通常是由使用者的操作或其他事件引起的。
  2. 這個 Action 被送到 Reducer,Reducer 根據 Action 的類型來修改應用程式的狀態。
  3. 修改後的狀態被存放在 Store 中,它是整個應用程式的狀態管理中心。
  4. 當狀態改變時,View 會被更新以反映新的狀態。
  5. 這個流程可以一直循環,每當有新的 Action 被觸發,就會再次進行狀態的修改和更新。

這就是 Redux 的基本運作流程。希望這個 Mermaid 流程圖有助於你更清楚地理解 Redux 的運作方式。如果你需要更多詳細資訊或有其他問題,請隨時告訴我。

畫成流程圖的話就會是這樣
https://ithelp.ithome.com.tw/upload/images/20231005/20135750VsMiyBWXhK.png

所以Redux用這樣的模式來更新「Store」,也就是原本的狀態(State)集結成庫
來看一下如何開始使用Redux以及範例程式碼

React Redux 範例

https://ithelp.ithome.com.tw/upload/images/20231005/20135750eqtwRI3QEo.png

當然可以!首先,讓我為你介紹一下 React Redux。

關於 React Redux

React Redux 是一個結合了 React 和 Redux 的庫,用於更有效地管理 React 應用程式的狀態。它幫助你在 React 應用中更容易地使用 Redux。

React Redux 提供了兩個主要的元件來實現這個整合:

  1. Provider: Provider 是一個 React 元件,它使你的整個應用程式能夠訪問 Redux Store。你只需要在你的應用程式的最上層使用 Provider,就可以讓所有的子元件都能使用 Redux。
  2. connect 函式: connect 函式是一個用於連接 React 元件和 Redux Store 的函式。它會將 Store 中的狀態以及 Action 傳遞給相關的 React 元件。

現在,讓我們來製作一個簡單的 ToDo List 的範例,並使用 functional component 以及 hook 來實現它。

ToDo List 範例

步驟 1:建立 Redux Store

首先,你需要安裝 Redux 和 React Redux:

npm install redux react-redux

然後,在你的應用程式中建立一個 Redux Store:

// src/store.js
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

export default store;

步驟 2:建立 Reducer

建立一個簡單的 Reducer 來處理 ToDo List 的狀態:

// src/reducers/todoReducer.js
const initialState = {
  todos: [],
};

const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        ...state,
        todos: [...state.todos, action.payload],
      };
    case 'REMOVE_TODO':
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload),
      };
    default:
      return state;
  }
};

export default todoReducer;

步驟 3:建立 Action Creators

創建一些 Action Creators 來描述你要進行的操作:

// src/actions/todoActions.js
export const addTodo = (todo) => {
  return {
    type: 'ADD_TODO',
    payload: todo,
  };
};

export const removeTodo = (id) => {
  return {
    type: 'REMOVE_TODO',
    payload: id,
  };
};

步驟 4:建立 ToDoList 元件

使用 functional component 和 hook 來建立 ToDo List 元件:

// src/components/ToDoList.js
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, removeTodo } from '../actions/todoActions';

const ToDoList = () => {
  const [input, setInput] = useState('');
  const todos = useSelector(state => state.todos);
  const dispatch = useDispatch();

  const handleAddTodo = () => {
    dispatch(addTodo({ id: Date.now(), text: input }));
    setInput('');
  };

  const handleRemoveTodo = (id) => {
    dispatch(removeTodo(id));
  };

  return (
    <div>
      <h2>ToDo List</h2>
      <div>
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
        />
        <button onClick={handleAddTodo}>Add</button>
      </div>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => handleRemoveTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default ToDoList;

步驟 5:使用 Provider 連接應用程式

在你的應用程式的最上層,使用 Provider 來連接 Redux Store:

// src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import ToDoList from './components/ToDoList';

function App() {
  return (
    <Provider store={store}>
      <div className="App">
        <ToDoList />
      </div>
    </Provider>
  );
}

export default App;

這樣就完成了一個簡單的 ToDo List 應用程式,並且使用了 React Redux 來管理狀態。希望這份範例能對你有所幫助!如果你有任何問題或需要進一步的說明,請隨時告訴我。

照著上面的的資料夾結構與範例程式碼複製貼上之後,真的可以跑出一個很陽春的TODO List
https://ithelp.ithome.com.tw/upload/images/20231005/20135750bFKhySXx2f.png

不過對於語法相當的輕描淡寫帶過
我們請ChatGPT在補上TypeScript的同時,也對語法做更詳細的解析

加上TypeScript

https://ithelp.ithome.com.tw/upload/images/20231005/20135750UKNKX2hRdN.png

當然,我會為你提供使用 TypeScript 的 ToDo List 範例,並提供語法講解。

首先,讓我們來更新之前的程式碼以適應 TypeScript。

步驟 1:建立 Redux Store

首先,確保你的應用程式已經安裝了 Redux 和 React Redux。然後,建立 Redux Store 的程式碼:

// src/store.ts
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

export default store;

在這個例子中,我們使用了 .ts 擴展名,表示這是 TypeScript 檔案。

步驟 2:建立 Reducer

更新 ToDo Reducer 以支援 TypeScript。在 src/reducers/todoReducer.ts 中的程式碼如下:

// src/reducers/todoReducer.ts
interface Todo {
  id: number;
  text: string;
}

interface TodoState {
  todos: Todo[];
}

const initialState: TodoState = {
  todos: [],
};

type TodoAction = { type: 'ADD_TODO'; payload: Todo } | { type: 'REMOVE_TODO'; payload: number };

const todoReducer = (state = initialState, action: TodoAction): TodoState => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        ...state,
        todos: [...state.todos, action.payload],
      };
    case 'REMOVE_TODO':
      return {
        ...state,
        todos: state.todos.filter((todo) => todo.id !== action.payload),
      };
    default:
      return state;
  }
};

export default todoReducer;

在這裡,我們使用 TypeScript 定義了 TodoTodoState 介面,以及 TodoAction 類型,以確保我們的 Reducer 遵循正確的類型。

步驟 3:建立 Action Creators

更新 Action Creators 以支援 TypeScript。在 src/actions/todoActions.ts 中的程式碼如下:

// src/actions/todoActions.ts
interface Todo {
  id: number;
  text: string;
}

export const addTodo = (todo: Todo) => {
  return {
    type: 'ADD_TODO',
    payload: todo,
  };
};

export const removeTodo = (id: number) => {
  return {
    type: 'REMOVE_TODO',
    payload: id,
  };
};

在這裡,我們使用 Todo 介面來定義 Action 的 payload

步驟 4:建立 ToDoList 元件

更新 ToDoList 元件以支援 TypeScript。在 src/components/ToDoList.tsx 中的程式碼如下:

// src/components/ToDoList.tsx
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, removeTodo } from '../actions/todoActions';
import { RootState } from '../reducers/rootReducer'; // 引入根 Reducer 的類型

const ToDoList: React.FC = () => {
  const [input, setInput] = useState<string>('');
  const todos = useSelector((state: RootState) => state.todoReducer.todos); // 使用 RootState 來確保正確的類型
  const dispatch = useDispatch();

  const handleAddTodo = () => {
    dispatch(addTodo({ id: Date.now(), text: input }));
    setInput('');
  };

  const handleRemoveTodo = (id: number) => {
    dispatch(removeTodo(id));
  };

  return (
    <div>
      <h2>ToDo List</h2>
      <div>
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
        />
        <button onClick={handleAddTodo}>Add</button>
      </div>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => handleRemoveTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default ToDoList;

在這裡,我們使用了 React.FC 類型定義 ToDoList 元件,同時也使用了 RootState 來確保正確的類型。

步驟 5:使用 Provider 連接應用程式

最後,確保你的應用程式的最上層使用 Provider 來連接 Redux Store,這部分的程式碼不需要修改。

現在,你的 ToDo List 應用程式已經使用 TypeScript 進行了更新。這能確保你的程式在編譯時檢測到類型錯誤,有助於提高程式碼的可靠性。

希望這份 TypeScript 版的範例和說明對你有所幫助!如果你有任何問題或需要進一步的說明,請隨時告訴我。

變成TypeScript了,但是還是沒有講解多少
有疑惑的還是直接問比較快
https://ithelp.ithome.com.tw/upload/images/20231005/20135750sGdyVLIGSq.png

useSelectoruseDispatch 是 React Redux 提供的兩個 hook,它們用於在 functional component 中使用 Redux。

useSelector

useSelector 是一個用來從 Redux Store 中選擇(或者說提取)狀態的 hook。它接收一個函式作為參數,這個函式接收整個 Redux State 作為參數,並返回你想要的狀態。

舉例來說,如果你的 Redux State 包含一個 counter 的狀態,你可以透過 useSelector 來選擇這個狀態:

import { useSelector } from 'react-redux';

const CounterComponent = () => {
  const counter = useSelector(state => state.counter);

  return <div>Counter: {counter}</div>;
};

這個例子中,useSelector 會返回 state.counter 的值,然後你可以在組件中使用這個值。

useDispatch

useDispatch 是一個用來發送 Action 到 Redux Store 的 hook。它返回一個 dispatch 函式,你可以使用這個函式來派發 Action。

舉例來說,如果你有一個 Action Creator 叫做 increment,你可以透過 useDispatch 來派發這個 Action:

import { useDispatch } from 'react-redux';
import { increment } from './actions';

const CounterComponent = () => {
  const dispatch = useDispatch();

  const handleIncrement = () => {
    dispatch(increment());
  };

  return (
    <div>
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
};

在這個例子中,當按下按鈕時,handleIncrement 會派發 increment Action 到 Redux Store。

簡單來說,useSelector 用來選擇狀態,而 useDispatch 用來派發 Action 到 Redux Store。

希望這能幫助你理解這兩個 hook 的作用!如果你有任何進一步的問題,請隨時告訴我。

學習完新語法,再把這些語法以及名詞的關係畫一個流程圖看看
https://ithelp.ithome.com.tw/upload/images/20231005/20135750OrY6SpJjZz.png

當然,我可以使用 Mermaid 來簡單表示 useSelectoruseDispatch、Reducer 和 Action 之間的運作流程。以下是一個簡單的流程圖:

graph TD
  A[Component] -->|使用 useSelector| B[Redux Store]
  A -->|使用 useDispatch| C[Redux Store]
  C -->|dispatch| D[Reducer]
  D -->|處理 Action| E[新的狀態]
  E -->|返回新的狀態| B

在這個流程圖中,我們有以下幾個元素:

  • Component (元件):React 元件,使用 useSelectoruseDispatch 來訪問 Redux Store 和派發 Action。
  • Redux Store (Redux 儲存庫):Redux 中的儲存庫,存放整個應用程式的狀態。
  • Reducer (處理器):處理 Action,根據 Action 來修改應用程式的狀態。
  • Action (行動):描述發生了什麼事件,使用 useDispatch 來派發到 Reducer。
  • 新的狀態:處理後的狀態,由 Reducer 返回並存放在 Redux Store 中。

流程如下:

  1. React 元件(Component)使用 useSelector 來選擇需要的狀態從 Redux Store 中提取。
  2. React 元件(Component)使用 useDispatch 來派發 Action 到 Redux Store。
  3. 派發的 Action 進入 Reducer(Reducer)處理。
  4. Reducer 根據 Action 的類型,修改應用程式的狀態。
  5. Reducer 返回新的狀態,並存放在 Redux Store 中。

這個流程圖簡單地展示了 React Redux 中 useSelectoruseDispatch、Reducer 和 Action 之間的互動關係。希望這能幫助你更好地理解它們之間的運作方式!如果你有任何進一步的問題,請隨時告訴我。

https://ithelp.ithome.com.tw/upload/images/20231005/201357504tmLh27uv9.png

使用Redux vs. 原本的useState

https://ithelp.ithome.com.tw/upload/images/20231005/20135750kxaYdLU7W8.png

當然,我可以提供一個不使用 Redux 的 ToDo List 範例,並與之前的使用 Redux 的範例進行比較,讓你了解兩者的優劣。

不使用 Redux 的 ToDo List 範例

以下是一個不使用 Redux 的簡單 ToDo List 範例:

import React, { useState } from 'react';

const ToDoList = () => {
  const [input, setInput] = useState('');
  const [todos, setTodos] = useState([]);

  const handleAddTodo = () => {
    if (input.trim() !== '') {
      setTodos([...todos, { id: Date.now(), text: input }]);
      setInput('');
    }
  };

  const handleRemoveTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  return (
    <div>
      <h2>ToDo List</h2>
      <div>
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
        />
        <button onClick={handleAddTodo}>Add</button>
      </div>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => handleRemoveTodo(todo.id)}>Remove</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default ToDoList;

在這個範例中,我們使用了 React 的 useState hook 來管理狀態,而不是 Redux。狀態(todos)和操作(新增、刪除)都被包含在同一個元件中。

比較優劣

使用 Redux 的優點:

  1. 統一的狀態管理: Redux 提供一個統一的 Store 來管理應用程式的狀態,這使得狀態更容易追蹤和管理,特別在大型應用程式中。
  2. 可預測性: Redux 的單向數據流和不可變的狀態修改使應用程式的行為更可預測,有助於減少錯誤。
  3. 方便的開發工具: Redux 提供了強大的開發工具,可以輕鬆追蹤狀態變化、偵錯和時間旅行式除錯。
  4. 跨元件共享狀態: Redux 允許多個元件輕鬆共享相同的狀態,而不需要通過 props 進行深層傳遞。

不使用 Redux 的優點:

  1. 簡單性: 不使用 Redux 可以使代碼更簡單,特別是對於小型應用程式或簡單的元件來說,可以減少額外的 Redux 相關代碼。
  2. 學習曲線: 如果你是初學者,學習 React 和 Redux 可能會有一定的學習曲線。不使用 Redux 可以讓你更快地開始建立應用程式。

總之,使用 Redux 的主要優勢在於管理複雜的狀態和提供開發工具,特別適用於大型應用程式。但對於小型應用程式或初學者來說,不使用 Redux 可能更簡單和快速上手。

選擇是否使用 Redux 取決於你的專案需求和個人偏好。對於大型應用程式,或需要高度可預測性和測試性的專案,Redux 可能是一個不錯的選擇。對於小型專案或初學者,不使用 Redux 也可以是一個合理的選擇。

Reducer

https://ithelp.ithome.com.tw/upload/images/20231005/20135750LcmZ3GCUQw.png

在撰寫 Redux 中的 Reducer 時,有一些重要的原則需要遵守,以確保程式碼的正確性和可維護性:

原則 1:純函式 (Pure Function)

正確示例:

const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

錯誤示例:

let count = 0;

const reducer = (action) => {
  switch (action.type) {
    case 'INCREMENT':
      count++;
      return count;
    case 'DECREMENT':
      count--;
      return count;
    default:
      return count;
  }
};

說明: Reducer 必須是純函式,這意味著它的執行結果必須完全由輸入決定,不得有副作用。純函式不會改變傳入的參數,也不會改變其他地方的狀態或資料。

原則 2:不得修改傳入的 state

正確示例:

const reducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return { ...state, todos: [...state.todos, action.payload] };
    case 'REMOVE_TODO':
      return { ...state, todos: state.todos.filter(todo => todo.id !== action.payload) };
    default:
      return state;
  }
};

錯誤示例:

const reducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      state.todos.push(action.payload); // 修改了傳入的 state
      return state;
    case 'REMOVE_TODO':
      state.todos = state.todos.filter(todo => todo.id !== action.payload); // 修改了傳入的 state
      return state;
    default:
      return state;
  }
};

說明: Reducer 不得直接修改傳入的 state,應該返回一個新的狀態物件。這保證了 Redux 的單向數據流。

原則 3:返回一個新的狀態物件

正確示例:

const reducer = (state, action) => {
  switch (action.type) {
    case 'SET_USER':
      return { ...state, user: action.payload };
    default:
      return state;
  }
};

錯誤示例:

const reducer = (state, action) => {
  switch (action.type) {
    case 'SET_USER':
      state.user = action.payload; // 修改了原始狀態
      return state;
    default:
      return state;
  }
};

說明: Reducer 應該總是返回一個全新的狀態物件,而不是修改原始狀態。

原則 4:預設返回原始狀態

正確示例:

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

說明: 在 Reducer 中,應該總是返回一個合理的狀態。如果沒有匹配到任何 action type,則應該返回原始狀態。

這些原則是為了確保 Redux 應用程式的正確運作和易於維護。遵循這些原則能幫助你寫出高質量的 Redux 代碼。如果你有任何問題或需要進一步的說明,請隨時告訴我。

統整重點

https://ithelp.ithome.com.tw/upload/images/20231005/20135750EGZmm8Bud3.png

在這次的對話中,我們探討了以下主題:

  1. React Redux:React Redux 是一個結合了 React 和 Redux 的庫,用於更有效地管理 React 應用程式的狀態。它提供了兩個主要的元件,Providerconnect,讓 React 元件能夠訪問 Redux Store。
  2. useSelectoruseDispatch:這兩個是 React Redux 提供的 hook,用於在 functional component 中使用 Redux。useSelector 用於選擇狀態,useDispatch 用於派發 Action 到 Redux Store。
  3. Reducer 的原則:
    • 純函式 (Pure Function):Reducer 必須是純函式,執行結果完全由輸入決定,不得有副作用。
    • 不得修改傳入的 state:Reducer 不得直接修改傳入的 state,應該返回一個新的狀態物件。
    • 返回一個新的狀態物件:Reducer 應該總是返回一個全新的狀態物件,而不是修改原始狀態。
    • 預設返回原始狀態:Reducer 應該總是返回一個合理的狀態,如果沒有匹配到任何 action type,則應該返回原始狀態。

總結來說,React Redux 是一個強大的工具,可以幫助我們更有效地管理 React 應用程式的狀態。useSelectoruseDispatch 讓我們在 functional component 中更容易地使用 Redux。在編寫 Reducer 時,我們需要遵守一些重要的原則,如保持它們是純函式、不修改傳入的 state,並始終返回一個新的狀態物件。

選擇是否使用 Redux 取決於專案需求和個人偏好。Redux 適用於大型、複雜的應用程式,提供了一個統一的狀態管理解決方案。然而,對於小型應用程式或初學者來說,可能會覺得不使用 Redux 更簡單和直觀。

無論選擇了哪種方法,重要的是理解這些概念並遵循最佳實踐,以確保你的應用程式能夠保持可靠和易於維護。如果你有任何進一步的問題或需要協助,請隨時告訴我!

結語

本次的對話內容記錄在這裡:
https://chat.openai.com/share/e64a60e8-ae89-40fa-847f-77e6616eaf16

redux看起來真的會比較複雜,因此適合用在大型複雜的專案中
也尤其那種State要傳好幾個Component、好多種動作需要更改同一種state內容的

定義Reducer和action 、還要寫action creator等等的程序看起來很繁雜
但下一章節會介紹 Redux Toolkit,官方推出的toolkit
能夠用更簡易且整合的方式來定義reducer與action

但了解Redux基本概念與流程,reducer與action和store的關係是重要的
我是redux放一篇介紹放不完的前端工程師一宵三筵,我們明天見QQ


上一篇
【Day22】ChatGPT請教教我:React入門(八)- React & axios !API串起來!
下一篇
【Day24】ChatGPT請教教我:React進階(二)- React Redux & Redux Toolkit!
系列文
用ChatGPT詠唱來完成工作與點亮前後端技能樹56
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言