iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0

在進入到明天的主題之前,先來認識兩個詞彙.分別是Controlled Component和UnControlled Component。這個部分不會複雜,但是與後面接著要來看的一個主題有關。好啦!廢話不多說,直接進主題。

什麼是Controlled Component & Uncontrolled Component

從字面上來看的話,一個是可控的元件,一個是不可控的元件,那在這裡可控和不可控是指那個部分呢?指的就是「元件的state」。這裡可以稍微思考一下,在什麼樣的狀況下,元件的state可以被控制。其實如果想要控制state,很重要的一件事就是是否擁有那個state,因為要擁有,才有辦法控制。
單用文字說明可能不好理解,直接來看一個情境,以下是一個很簡單的input的使用情境。

Uncontrolled Component
這個input的value由DOM自己管理,沒有另外綁定React或Vue所管理的state,所以想要取得input的值,需要透過DOM來取得。

return (
  <div>
    <input type="text" />
  </div>
);

Controlled Component
以下這兩個範例中input的value有綁定React或是vue的state,所以可以很輕鬆地透過React和Vue的方式取得input的value。

// Vue
<template>
  <div>
    <input type="text" v-model="inputValue" />
  </div>
</template>

<script setup>
import { ref } from 'vue';

const inputValue = ref('');
</script>
// React
import React, { useState } from 'react';

const ControlledInput = () => {
  const [inputValue, setInputValue] = useState('');

  const handleInputChange = (e) => {
    setInputValue(e.target.value);
  };

  return (
    <div>
      <input type="text" value={inputValue} onChange={handleInputChange} />
    </div>
  );
};

export default ControlledInput;

在上述input例子的Controlled Component中,vue透過v-model把value和事件綁定在input上,React則透過綁定value及onChange事件取得input的value,不需要額外去透過DOM來取得value。

以上述例子來看Uncontroll和Controlled的差異,就是我們前面提到的「有沒有擁有元件的state」。雖然這兩個詞彙通常都是用在表單相關的元件上,但其實這樣個概念不限於表單元件。往更大的方向下去思考的話,可控和不可控其實帶有著父層元件是不是可以控制子層元件的意思。

關於React新舊官方文件的解釋差異

這裡也來看看一個有趣的地方,那就是React的新舊版官方文件對Controlled和Uncontrolled有著不太一樣的解釋。

React舊版官方文件的說明

在舊版文件中,Controlled和Uncontrolled的定義指的是元件內的state有沒有受到React的控制,這裡的控制指的是有沒有「使用React的state。就如同前面的範例一樣,input有綁定一個React的state,就是一個React控制得了的元件。

React新版官方文件的說明

在新版文件中的Controll和Uncontrolled的定義則是 元件的狀態能否被父層控制,白話一點的話,也就是子元件有沒有暴露一些props接口讓父層可以透過props把父層自己的state帶入子元件中。例如以下這個元件,就是新版文件中定義的Controlled元件,因為可以控制元件的狀態都是從父層傳入。

const TodoItem = ({ todoItem, toggleComplete }) => {
  return (
    <li className="todo-item">
      <p className={todoItem.complete ? 'completed' : ''}>{todoItem.content}</p>
      <input
        type="checkbox"
        checked={todoItem.complete}
        onChange={() => toggleComplete(todoItem.id)}
      />
    </li>
  );
};

雖然新舊版對於Controlled和Uncontrolled有著不太一樣的解釋,不過其實重點還是在「有沒有辦法控制」的這個部分,只是舊版文件的定義比起新版文件的定義再狹義一點,但那個概念還是相同。

通常如果是客製化的元件,為了方便使用都會設計為Controlled元件,這樣的設計也能讓這個元件能夠更靈活地使用在各個地方。但是偶爾還是會有一些情境(例如使用外部套件設計的元件)會使用到一些Uncontrolled元件,但又必須要有辦法控制這樣的元件,這個時候就會需要透過一些方法來讓這個Uncontrolled元件變得可以控制。今天先簡單地看了一下Controlled和Uncontrolled的概念後,明天就接著來看看當這樣的情境出現時,可以利用什麼方式控制這個Uncontrolled的元件。

參考文件

舊的React官網
新的React官網


上一篇
【Day 18】優化頁面效能的另一個方向-lazy & Suspense
下一篇
【Day 20】用ref讓Uncontrolled元件變可控
系列文
從Vue學React!不只要會用,還要真的懂~30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言