React 父子元件間的溝通

感覺在每個框架都得學的觀念。

簡述

這邊會拿我做的垃圾 Todo list 來當範例:

todo-list

它的結構長這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function App() {
const [todos, setTodos] = useState([
{
id: 0,
content: '吃飯',
isDone: true
},
{
id: 1,
content: '寫文章',
isDone: false
},
{
id: 2,
content: '寫程式',
isDone: false
},
])


return (
<div style={rootStyle}>
<TodoHeader addTodo={addTodo}></TodoHeader>
{todos.map(todo => <TodoItem key={todo.id} todo={todo}</TodoItem>)}
</div>
);
}

如果懶得看 code 的話,那就參考下面:

  • App
    • TodoHeader(上面的輸入區塊)
    • TodoItem(下面的 Todo 列表)

現在的問題是,「如果 Todo 的狀態是儲存在 App 上,那我按下刪除按鈕時要怎麼去改到 App 的 State?」

其實解法還蠻直覺的,只是要稍微想一下就是了。

既然我們可以透過 props 把東西傳到子元件上,那我直接傳一個 function 不就好了嗎?

像是這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function App() {
const [todos, setTodos] = useState([
{
id: 0,
content: '吃飯',
isDone: true
},
{
id: 1,
content: '寫文章',
isDone: false
},
{
id: 2,
content: '寫程式',
isDone: false
},
])


// 用來變更 state 的 function
// 預期會傳入一個 id
const handleRemoveTodo = id => {
setTodos(todos.filter(todo => todo.id !== id))
}

return (
<div style={rootStyle}>
// 透過 props 傳給子層
<TodoHeader handleRemoveTodo={handleRemoveTodo}></TodoHeader>
{todos.map(todo => <TodoItem key={todo.id} todo={todo}</TodoItem>)}
</div>
);
}

接著就可以在子層接到這個 props

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 接收 props
function TodoItem ({ todo, handleRemoveTodo }) {

// 按下按鈕的 handler
const handleButtonClick = () => {
// 去 call 父層傳進來的 function,並帶入 id
handleRemoveTodo(Number(e.target.getAttribute('data-id')))
}

return (
<TodoItemWrapper>
<TodoContent>{todo.content}</TodoContent>
<TodoButtonWrapper>
<GreenButton
isDone={todo.isDone}
data-id={todo.id}
onClick={handleButtonClick}>{todo.isDone ? '已完成' : '未完成'}
</GreenButton>
<RedButton data-id={todo.id}>刪除</RedButton>
</TodoButtonWrapper>
</TodoItemWrapper>
)
}

如此一來,就可以從子層去改變父層的 state,這就是元件之間的溝通方式,透過 props。

React 關於 state 的一些概念 mentor-program-day112
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×