iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0

前言:昨天讀到關於物件的淺、深拷貝,釐清關於JavaScript中物件操作要注意部分。

下一章節,書上提到 Call by value、Call by reference、Call by sharing 又是代表甚麼?

  • Call by Value: 傳遞的是值的複製體,對複製體的修改不會影響原始值。

  • Call by Reference: 傳遞的是物件的引用,對引用的修改會影響原來物件。

  • Call by Sharing: 類似於引用傳遞,但物件本身不能被重新分配,重新分配只會影響局部變量,不會影響原始物件。

當了解了 Call by Value、Call by Reference 和 Call by Sharing 的概念後,在撰寫 React 代碼時可以更好地管理狀態,避免不必要的副作用和重新渲染。以下是一些具體的應用場景,展示如何在 React 中應用這些概念。

  1. Call by Value
    在 React 中,當傳遞原始類型(如數字、字符串、布爾值)作為函數參數時,它們是按值傳遞的。這意味著修改函數內部的參數不會影響原始變量。
function increment(value) {
  value += 1;
  return value;
}

let count = 0;
let newCount = increment(count);

console.log(count); // 0
console.log(newCount); // 1

在這個例子中,count 的值不會被函數 increment 修改。

  1. Call by Reference
    當傳遞物件或數組作為函數參數時,它們是按引用傳遞的。這意味著修改函數內部的參數會影響原始物件。
function addItem(arr) {
  arr.push("new item");
}

let items = ["item1", "item2"];
addItem(items);

console.log(items); // ["item1", "item2", "new item"]

在這個例子中,items 數組被 addItem 函數修改。

  1. Call by Sharing
    在 JavaScript 中,物件的傳遞實際上是按共享傳遞的。這意味著物件的屬性可以被修改,但物件的引用無法被重新分配。這在 React 中尤為重要,因為狀態更新必須創建新的物件,而不是直接修改原始物件。
function updateObject(obj) {
  obj.newProp = "new value"; // 修改屬性
  obj = { anotherProp: "another value" }; // 試圖重新分配引用
  console.log(obj); // { anotherProp: "another value" }
}

let myObject = { prop: "value" };
updateObject(myObject);

console.log(myObject); // { prop: "value", newProp: "new value" }

在這個例子中,updateObject 函數修改了 myObject 的屬性,但重新分配的引用只影響了局部變量,不會影響原始物件。

在 React 中的應用
理解這些概念後,可以在 React 中更好地管理狀態和避免不必要的重新渲染。

  1. 避免直接修改狀態
    在 React 中,狀態更新應該使用不可變操作。直接修改狀態物件可能導致不可預測的行為和性能問題。
function App() {
  const [items, setItems] = useState(["item1", "item2"]);

  const addItem = () => {
    setItems([...items, "new item"]);
  };

  return (
    <div>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
      <button onClick={addItem}>Add Item</button>
    </div>
  );
}
  1. 深拷貝與狀態管理
    如果狀態包含深層嵌套的物件,使用深拷貝來避免不必要的副作用。
function App() {
 const [state, setState] = useState({ nested: { prop: "value" } });

 const updateState = () => {
   // 使用深拷貝創建新物件
   const newState = JSON.parse(JSON.stringify(state));
   newState.nested.prop = "new value";
   setState(newState);
 };

 return (
   <div>
     <p>{state.nested.prop}</p>
     <button onClick={updateState}>Update State</button>
   </div>
 );
}
  1. 狀態管理庫的使用
    在使用 Redux 或其他狀態管理庫時,理解這些概念有助於更好地管理應用狀態,避免不必要的狀態變更和重新渲染。
import { createStore } from "redux";

// 定義初始狀態
const initialState = { count: 0 };

// 定義 reducer 函數
function counterReducer(state = initialState, action) {
  switch (action.type) {
    case "INCREMENT":
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
}

// 創建 Redux store
const store = createStore(counterReducer);

store.subscribe(() => console.log(store.getState()));

// 分派動作
store.dispatch({ type: "INCREMENT" }); // { count: 1 }

在這個例子中,counterReducer 使用不可變操作更新狀態,這樣可以確保狀態變更是可預測的,並且不會導致不必要的重新渲染。

理解 Call by Value、Call by Reference 和 Call by Sharing 的概念,能有助在 React 中更好的管理狀態,避免不必要的副作用和性能問題。通過使用不可變操作、深拷貝和狀態管理庫,可以確保應用狀態的穩定性和可預測性。


上一篇
[Day 9] 物件原來還分淺層複製及深層複製(二)
下一篇
[Day 11] JavaScript有陣列嗎?
系列文
讀書筆記&心得-看完這本就會懂!帶你無痛提升JavaScript面試力:精選55道前端工程師的核心問題 × 求職加分模擬試題解析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言