Bạn chưa hiểu về setState đâu!!
Trong React component là thành phần cốt lõi để tạo nên giao diện người dùng, trong mỗi component thường có props hoặc state hiểu đơn giản component sử dụng props và state để có dữ liệu từ đó vẽ lên giao diện.
Theo một cách nhìn khác component như một hàm nhận dữ liệu đầu vào là props và dữ liệu cục bộ của hàm chính là state, state và props chính là dữ liệu giúp cho component xây dựng nên giao diện như mình nói bên trên, khi bạn muốn thay đổi tính chất hay hành vi của component một trong những cách phổ biến chính là setState.
Hàm setState nhìn qua rất đơn giản nhưng nếu không hiểu bản chất cũng như một số hành vi bất thường của nó sẽ khiến cho ra những kết quả không mong muốn trong bài viết này mình sẽ trình bày nhưng điểm cần chú ý khi sử dụng hàm setState giúp các bạn có thể sử dụng hàm này một cách hiệu quả hơn, tránh tác dụng không mong muốn ^^.
Theo một cách nhìn khác component như một hàm nhận dữ liệu đầu vào là props và dữ liệu cục bộ của hàm chính là state, state và props chính là dữ liệu giúp cho component xây dựng nên giao diện như mình nói bên trên, khi bạn muốn thay đổi tính chất hay hành vi của component một trong những cách phổ biến chính là setState.
Hàm setState nhìn qua rất đơn giản nhưng nếu không hiểu bản chất cũng như một số hành vi bất thường của nó sẽ khiến cho ra những kết quả không mong muốn trong bài viết này mình sẽ trình bày nhưng điểm cần chú ý khi sử dụng hàm setState giúp các bạn có thể sử dụng hàm này một cách hiệu quả hơn, tránh tác dụng không mong muốn ^^.
setState có thể bất đồng bộ.
Như mình đã trình bày ở bài viết về Dom ảo, React không thực hiện cập nhật state thực ngay lập tức khi một setState được kích hoạt thay vào đó React cập nhật theo từng đợt (Batch Update), nó gom từng đợt setState trong component để tối ưu hóa về hiệu năng.
=> Đó chính là lý do bạn không thấy giá trị của state ngay sau khi bạn setState.
Nếu như bạn call nhiều setState (truyền vào Object) liền nhau bạn nghĩ rằng React chạy từng hàm rồi đồng state sau đó cập nhật dữ liệu vào Dom thực => đây là quan niệm sai lầm.
Khi call multi setState React sẽ không chạy hết nó sẽ gom lại và chỉ chấp nhận lần setState cuối cùng giống như hình sau.
=> Giá trị state mà bạn mong đợi chi có sẵn sau khi hàm render đã được thực hiện xong.
Khi call multi setState React sẽ không chạy hết nó sẽ gom lại và chỉ chấp nhận lần setState cuối cùng giống như hình sau.
=> Giá trị state mà bạn mong đợi chi có sẵn sau khi hàm render đã được thực hiện xong.
Lúc này count sẽ có giá trị bằng 1 do object trước bị ghi đè bởi giá trị sau vì các object này trùng key nhau.
setState có thể chấp nhận đối số đầu vào là một callback
Bây giờ bạn call multil setState sẽ ra kết quả như ý muốn do nếu bạn truyền một callback vào setState thì React sẽ gọi nó lần lượt các hàm từ trên xuống dưới, giá trị đầu vào của mỗi hàm dựa vào kết quả của lần call setState gần nhất.
=> Chú ý rằng ngay cả khi bạn truyền một callback vào setState thì React vẫn gom các lần setState này lại với nhau để thực hiện batchUpdate chỉ khác rằng với callback thì React
=> Chú ý rằng ngay cả khi bạn truyền một callback vào setState thì React vẫn gom các lần setState này lại với nhau để thực hiện batchUpdate chỉ khác rằng với callback thì React
=> Từ đây mình rút ra kinh nghiệm rằng:
+Không tính toán giá trị của state phụ thuộc vào this.state ngay sau khi setState (liền kề)
+Nếu bạn muốn tính toán các giá trị state ngay sau khi setState thay vì sử dụng object để hợp nhất state thì sử dụng callback để update state đặc biêt là khi bạn phải cập nhật trạng thái nhiều lần liên tiếp.
setState có thể đồng bộ
Mình vừa nói rằng setState có thể bất đồng bộ (hầu hết các trường hợp), trong một số bối cảnh nhất định React chạy setState một cách đồng bộ.
Bất đồng bộ :
Đồng bộ:
Bất đồng bộ :
Đồng bộ:
Bản chất không đồng bộ của setState
Mình đã nói rằng React update theo kiểu Batch Update nó gom các lần call setState theo từng đợt để tối ưu hóa hiệu năng tránh cập nhật Dom thực nhiều lần không cần thiết tuy nhiên trong một số trường hợp React không kiểm soát được các đợt update này do đó state sẽ được cập nhật đồng bộ (ngay lập tức) ví dụ: eventListender, AJAX, setTimeout hoặc các API WEB do browser cung cấp.
Bạn có thể thấy rằng với các tình huống sử dụng các hành vi bất đồng bộ React tiến hành cập nhật state và render lại component ngay lập tức mà không nhóm vào từng đợt nữa, bạn có hiểu vì sao ?
Hóa ra React không kiểm soát được những hành vi này trong component, do đó nó không dám gom nhóm các lần update state này thay vào đó React chọn giải pháp an toàn, nó render lại ngay lập tức mỗi lầm state thay đổi ^^.
Bạn muốn tính toán giá trị phụ thuộc vào state tại một trạng thái xác định của nó ?
Hàm setState khi nhận vào một object nó sẽ nhận vào thêm một đối số thứ 2 là một callback. Hàm callback sẽ được invoked sau khi state ở hàm này được cập nhật xong, chạy sau hàm render và chạy trước hàm componentDidUpdate.






Nhận xét
Đăng nhận xét