Hi 🤓 Cảm ơn bạn đã ghé thăm blog này, nếu những bài viết trên blog giúp ích cho bạn. Bạn có thể giúp blog hiển thị quảng cáo bằng cách tạm ngừng ad blocker 😫 và để giúp blog duy trì hoạt động nếu bạn muốn.
Cảm ơn bạn!

Shallow Compare trong React

Bạn đã nghe qua Shallow Compare trong React chưa? Nếu chưa thì trong bài viết này chúng ta cùng tìm hiểu xem nó là gì nhé. Mình sẽ lấy các ví dụ sử dụng Class Components để giải thích về Shallow Compare.

Như chúng ta đã biết, một component sẽ re-render lại khi chúng ta update state. Khi sử dụng Class Components để update state, chúng ta dùng this.setState(), React sẽ so sánh state trước và sau, nếu state thay đổi thì lúc này React sẽ re-render component 👍.

Vậy làm thế nào để React biết state đã thay đổi so với trước kia? Câu trả lời là React thực hiện Shallow Compare cho state cũ với state mới.

Vậy Shallow Compare trong React hoạt động thế nào? Shallow Compare có thể hiểu là so sánh sử dụng ===. Khi so sánh các primitives như number, string nó sẽ so sánh các giá trị của chúng. Tuy nhiên, khi so sánh các object, nó sẽ không so sánh các thuộc tính của chúng mà chỉ so sánh reference của chúng.

Giả sử ta có state sau:

this.state = {
  ten: "Trang",
  lop: "10A"
}

const user = this.state;
user.ten = "Linh";

Ta thử thay đổi giá trị ten của user và so sánh state vs user để xem kết quả. Bạn đoán xem kết quả sẽ là true hay false?

console.log(user === this.state); // true

Kết quả trả về là true 🤷‍♂️ Bởi vì khi chúng ta gán this.state cho user thì reference giống nhau, bạn có thể hiểu là chúng cùng trỏ về một địa chỉ trong bộ nhớ.

Cùng theo dõi ví dụ tiếp theo:

const user = {
    name: "Minh",
    born: "2000",
    phone: {
         viettel: 123,
         vinaphone: 423,
    }
}

const updated_user = {
    name: "Minh",
    born: "2000",
    phone: {
         viettel: 123,
         vinaphone: 423,
    }
}

Với ví dụ trên, chúng ta có thể hình dung React sẽ so sánh sử dụng Shallow Compare 2 object như thế này:

if(user.name !== updated_user.name 
   || user.born !== updated_user.born
   || user.phone !== updated_user.phone
  ) {
  console.log('state được update giá trị mới nên sẽ re-render');
}

Ở ví dụ trên khi so sánh user.phone !== updated_user.phone sẽ có kết quả là true. Lý do thì như ở trên mình đã nói, đối với so sánh object khi sử dụng === nó sẽ so sánh theo reference. Vì 2 object này có địa chỉ trong ô nhớ khác nhau nên chúng sẽ khác nhau ^^.

Shallow Compare có nghĩa là nó sẽ chỉ so sánh các thuộc tính thuộc first level trong object, chứ không so sánh chi tiết các level khác. Ví dụ như thế này: user.phone.viettel === updated_user.phone.viettel, với kiểu so sánh thế này thì chúng ta sẽ gọi nó là Deep Compare hay so sánh tất tần tật những gì bên trong object 😁.

Với Class Components extends React.Component, khi chúng ta update state sử dụng this.setState(), React sẽ không thực hiện Shallow Compare mà sẽ thực hiện gọi render() và re-render lại component.

Như lưu ý ở trên thì làm sao để giảm thiểu các re-render không cần thiết?

Thông thường chúng ta thường viết Class Components như thế này:

class MyComponent extends React.Component {
  //...
}

Nếu các bạn muốn React thực hiện Shallow Compare cho new/old props hay state thì có thể extends PureComponent:

class MyComponent extends React.PureComponent {
  //...
}

Nếu không thích PureComponent bạn có thể tự kiểm tra bằng cách sử dụng shouldComponentUpdate(), lifecycle method này sẽ ngăn không cho React re-render lại component khi method này return false. Chúng ta có thể kiểm tra các giá trị của state tại đây như sau:

shouldComponentUpdate(nextProps, nextState) {
  // Nếu không muốn component re-render bạn có thể return false luôn ^^.
  if(this.state.someVar === nextState.someVar) return false; 
  return true;
}

Tóm lại: Shallow Compare có nghĩa là khi so sánh 2 object(so sánh first level object) thì nó sẽ thực hiện kiểm tra xem hai giá trị có bằng nhau không trong trường hợp giá trị này thuộc primitive types như string, number. Trong trường hợp là object, nó chỉ kiểm tra tham chiếu(reference).

Nếu chúng ta Shallow Compare một object phức tạp chứa object khác, nó sẽ chỉ kiểm tra tham chiếu chứ không phải các giá trị bên trong đối tượng đó.

Kết luận

Như vậy là chúng ta đã tìm hiểu xong Shallow Compare trong React. Hy vọng bài viết sẽ giúp ích cho các bạn ^^.

Chúc các bạn học tốt.

Có thể bạn thích ⚡
homiedev
About Me

Hi, I'm @devnav. Một người thích chia sẻ kiến thức, đặc biệt là về Frontend 🚀. Trang web này được tạo ra nhằm giúp các bạn học Frontend hiệu quả hơn 🎉😄.

Chúc các bạn tìm được kiến thức hữu ích trong blog này 😁😁.