如何在子 component 裡觸發更新父 component 的資料
步驟 1:了解原理
-
React 沒有專門的子 component 向上溝通機制
React 的資料流是單向的,子 component 無法直接改變父 component 的 state。解決方式是父 component 將一個函式作為 props 傳遞給子 component,子 component 透過呼叫這個函式來間接觸發父 component 的 state 更新。 -
核心概念
-
父 component 定義 state 和一個更新 state 的函式。
-
將更新 state 的函式作為 props 傳給子 component。
-
子 component 在事件觸發(如按鈕點擊)時,呼叫父 component 傳來的函式,並傳遞需要更新的資料。
-
步驟 2:實作範例
以下是一個完整的範例,展示如何讓子 component 透過按鈕點擊來更新父 component 的 state。
2.1 建立父 component
父 component 負責管理 state 和定義更新 state 的函式。
// src/components/ParentComponent.jsx
import React, { useState } from "react";
import ChildComponent from "./ChildComponent";
function ParentComponent() {
// 定義 state,用來儲存資料
const [parentData, setParentData] = useState("這是父 component 的初始資料");
// 定義更新 state 的函式,這個函式會傳給子 component
const updateParentData = (newData) => {
setParentData(newData); // 更新父 component 的 state
};
return (
<div>
<h1>父 Component</h1>
<p>父 component 的資料: {parentData}</p>
{/* 將 updateParentData 函式作為 props 傳給子 component */}
<ChildComponent updateData={updateParentData} />
</div>
);
}
export default ParentComponent;
說明:
-
使用 useState 定義 parentData 作為父 component 的狀態。
-
定義 updateParentData 函式,接受新的資料並更新 state。
-
將 updateParentData 函式透過 props(updateData)傳遞給子 component。
2.2 建立子 component
子 component 接收父 component 傳來的回調函式,並在事件觸發時呼叫它。
// src/components/ChildComponent.jsx
import React from "react";
function ChildComponent({ updateData }) {
// 當按鈕被點擊時,呼叫父 component 傳來的 updateData 函式
const handleClick = () => {
const newData = "這是從子 component 傳來的更新資料";
updateData(newData); // 呼叫父 component 的函式,傳遞新資料
};
return (
<div>
<h2>子 Component</h2>
<button onClick={handleClick}>更新父 component 的資料</button>
</div>
);
}
export default ChildComponent;
說明:
-
子 component 透過 props 接收父 component 傳來的 updateData 函式。
-
當按鈕被點擊時,觸發 handleClick 函式,並呼叫 updateData,傳遞新的資料給父 component。
-
子 component 不需要管理自己的 state,只需負責觸發父 component 的更新。
2.3 在主應用程式中渲染父 component
確保父 component 被正確渲染。
// src/App.jsx
import React from "react";
import ParentComponent from "./components/ParentComponent";
function App() {
return (
<div>
<ParentComponent />
</div>
);
}
export default App;
步驟 3:執行結果
-
當你啟動應用程式時,畫面上會顯示:
-
父 component 的標題和初始資料(這是父 component 的初始資料)。
-
子 component 的標題和一個按鈕。
-
-
點擊子 component 的按鈕後,父 component 的資料會更新為 這是從子 component 傳來的更新資料。
步驟 4:進階範例 - 處理輸入框
如果子 component 需要讓使用者輸入資料並更新父 component,可以使用輸入框來實現。以下是修改後的範例:
4.1 修改父 component
保持不變,僅展示父 component 的程式碼以供參考:
// src/components/ParentComponent.jsx
import React, { useState } from "react";
import ChildComponent from "./ChildComponent";
function ParentComponent() {
const [parentData, setParentData] = useState("這是父 component 的初始資料");
const updateParentData = (newData) => {
setParentData(newData);
};
return (
<div>
<h1>父 Component</h1>
<p>父 component 的資料: {parentData}</p>
<ChildComponent updateData={updateParentData} />
</div>
);
}
export default ParentComponent;
4.2 修改子 component
加入輸入框,讓使用者輸入資料並傳給父 component。
// src/components/ChildComponent.jsx
import React, { useState } from "react";
function ChildComponent({ updateData }) {
// 子 component 自己的 state,用來管理輸入框的值
const [inputValue, setInputValue] = useState("");
// 當輸入框值改變時,更新 inputValue
const handleInputChange = (event) => {
setInputValue(event.target.value);
};
// 當按鈕被點擊時,將輸入框的值傳給父 component
const handleClick = () => {
updateData(inputValue); // 將輸入框的值傳給父 component
setInputValue(""); // 清空輸入框
};
return (
<div>
<h2>子 Component</h2>
<input
type="text"
value={inputValue}
onChange={handleInputChange}
placeholder="請輸入資料"
/>
<button onClick={handleClick}>更新父 component 的資料</button>
</div>
);
}
export default ChildComponent;
說明:
-
子 component 使用自己的 useState 來管理輸入框的值(inputValue)。
-
當輸入框值改變時,handleInputChange 更新 inputValue。
-
當按鈕被點擊時,handleClick 將 inputValue 傳給父 component 的 updateData 函式,並清空輸入框。
步驟 5:常見問題與解決方法
-
問題:為什麼不能直接在子 component 修改父 component 的 state?
- React 的單向資料流設計確保資料流動可預測,子 component 只能透過 props 接收資料或函式,無法直接修改父 component 的 state。
-
問題:如果父 component 要傳遞多個回調函式怎麼辦?
-
你可以傳遞多個回調函式作為 props,例如:
<ChildComponent
updateData={updateParentData}
updateOtherData={updateOtherParentData}
/>
-
-
問題:如果子 component 很深層(例如孫 component)怎麼辦?
- 如果層級很深,可以使用 React 的 Context API 或狀態管理工具(如 Redux)來避免過多的 props 傳遞。
步驟 6:總結
-
核心方法:父 component 傳遞回調函式給子 component,子 component 透過呼叫此函式來更新父 component 的 state。
-
程式碼結構:
-
父 component 管理 state 和回調函式。
-
子 component 接收回調函式並在事件觸發時呼叫。
-
-
範例應用:按鈕點擊或輸入框輸入都可以觸發父 component 的 state 更新。