React controlled component và uncontrolled component

Trong hầu hết các trường hợp chúng ta thường cài đặt các component trong react dưới dạng controlled components. Có thể hiểu controlled components là các dữ liệu trong form đều được React quản lí thường dưới dạng state hoặc store. Còn uncontrolled components thì khác, dữ liệu được lấy trực tiếp từ DOM. Để hiểu chi tiết ta sẽ đi sâu hơn vào 2 lại component này.

Controlled component

Đầu tiên tôi sẽ lấy một ví dụ về controlled component. Có thể bạn thấy ví dụ này sẽ rất quent huộc bởi vì hầu hết đa số các trường hợp ta đều dùng controlled component

class Form extends Component {
  constructor() {
    super();
    this.state = {
      name: '',
    };
  }

  handleNameChange = (event) => {
    this.setState({ name: event.target.value });
  };

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.state.name}
          onChange={this.handleNameChange}
        />
      </div>
    );
  }
}

Trong ví dụ trên bạn có thể thấy dữ liệu của form được lữu trữ/quản lí bởi state của component. Mỗi khi bạn thay đổi input thì handleNameChange được gọi và nó sẽ cập nhật giá trị mới cho state. Sau khi state thay đổi thì nó sẽ render lại form với giá trị tương ứng với giá trị của state. . Giá trị khởi tạo của state.name sẽ là một string rỗng ''. . Khi bạn gõ 'a' vào ô input thì handleNameChange sẽ được gọi và cập nhật lại giá trị mới cho state là a. Tiếp đó là ô input sẽ được render lại với giá trị là state.name . Khi bạn gõ tiếp 'b' thì logic cũng tương tự. Khi đó state.name sẽ có giá trị là 'ab' và giá trị này sẽ là giá trị của input khi render lại.

Trong ví dụ trên ta có thể thấy là giá trị của ô input luôn luôn tương ứng với giá trị 'state.name' của component. Ta có thể hiểu là ô input trong ví dụ trên luôn luôn hiển thị giá trị của state.name

Uncontrolled component

Tiếp theo ta sẽ đến với uncontrolled component. Để viết một uncontrolled component khá đơn giản là bạn sẽ ko viết các event bắt sự kiện thay đổi input trong form mà bạn sẽ sử dụng một tham chiếu trực tiếp đến DOM. Dưới đây là một ví dụ đơn giản

class NameForm extends React.Component {
  constructor(props) {
    super(props);
  }

  handleSubmit = event => {
    alert('A name was submitted: ' + this.input.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={(input) => this.input = input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

Trong ví dụ trên, ta đặt một biến tham chiếu là input tham chiếu đến DOM object. Khi cần lấy giá trị ta sẽ truy xuất giá trị thông qua tham chiếu này.

Chú ý: Việc khởi tạo giá trị cho input trong trường hợp dùng uncontrolled component khác với controlled component. Bạn ko thể dùng thuộc tính value mà dùng thuộc tính defaultValue bởi vì nếu bạn dùng thuộc tính value thì mỗi khi form render lại nó sẽ luôn set giá trị này cho input, còn defaultValue chỉ set duy nhất lần đầu tiên khi khởi tạo form.

Vậy uncontrolled component dùng trong hoàn cảnh nào?

Theo tôi uncontrolled component nên dùng cho các hệ thống, chức năng đơn giản. Khi đó sẽ phát huy được ưu điểm của nó là cài đặt đơn giản và nhanh. Hơn nữa tương tác người dùng sẽ tốt hơn bởi vì trang web sẽ ko phải render lại mỗi lần thay đổi giá trị của input.

Đối với một chức năng phức tạp các dữ liệu có liên hệ mật thiết với nhau hoặc có nhiều logic liên quan đến dữ liệu thì bạn nên cài đặt với controlled components (quản lí dữ liệu với state hoặc store). Như thế sẽ làm cho dữ liệu của bạn trở nên rõ ràng và dễ quản lí hơn rất nhiều.

Ta có một bảng so sánh với uncontrolled componentcontrolled component

feature uncontrolled controlled
Lấy dữ liệu từ input
Validate dữ liệu khi submit
Validate của input mỗi khi thay đổi input
Validate cả form mỗi khi một input trong form thay đổi
Đảm bảo input theo một format nào đấy
Số lượng inputs trong form thay đổi tùy theo điều kiện

Từ bảng trên bạn có thể thấy là với controlled component bạn có thể làm rất nhiều việc. Tuy nhiên với sự đơn giản của uncontrolled component nó vẫn được sử dụng tốt với những form đơn giản không có nhiều yêu cầu đặc biệt.

Tham khảo:

  1. https://reactjs.org/docs/uncontrolled-components.html
  2. https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/

All Rights Reserved