restate / v1.0.0
Chỉ đăng ký những gì bạn cần
Chọn phần store mà mỗi component phụ thuộc, so sánh đối tượng bằng shallow, gom thay đổi bằng batch và nối các sự kiện bên ngoài.
Trên trang này
Truyền selectorThử ngayChọn nhiều trường với shallowSo sánh tùy chỉnhGom thay đổi bằng batchĐăng ký bên ngoài ReactNối sự kiện bên ngoàiTruyền selector
Gọi hook với một hàm chọn những gì component cần. Sau mỗi thay đổi, restate chạy selector và so sánh kết quả với lần trước bằng Object.is. Nếu bằng nhau, component không render.
Thẻ thay đổi. ItemCount có render không?
Không. selector của nó vẫn trả về cùng số lượng sản phẩm, nên phần chọn bằng nhau và React không được yêu cầu render.
const useCart = restate({ items: ['Book'], coupon: '', note: '' });
function ItemCount() {
// Re-renders only when the number of items changes.
const count = useCart((cart) => cart.items.length);
return <p>{count} items</p>;
}Thử ngay
Thay đổi các trường và theo dõi bộ đếm render. Tắt shallow để thấy một selector luôn trả về đối tượng mới.
Đang chuẩn bị ví dụ…
Chọn nhiều trường với shallow
Khi selector dựng một đối tượng, nó trả về đối tượng mới mỗi lần, nên Object.is luôn thấy thay đổi. Truyền shallow làm đối số thứ hai: nó so sánh các trường riêng của đối tượng ở độ sâu một cấp.
shallow cũng so sánh phần tử của mảng, Map và Set ở độ sâu một cấp.
import { restate, shallow } from '@kkwaenggwari/restate';
function CartSummary() {
const { count, coupon } = useCart(
(cart) => ({ count: cart.items.length, coupon: cart.coupon }),
shallow,
);
return (
<p>
{count} items · {coupon || 'no coupon'}
</p>
);
}So sánh tùy chỉnh
Bất kỳ hàm (left, right) => boolean nào cũng dùng được làm đối số thứ hai. Dùng khi shallow chưa đủ, ví dụ để so sánh danh sách theo id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Gom thay đổi bằng batch
Mỗi lần set thông báo ngay cho bên đăng ký. Khi một hành động đổi nhiều store, hãy bọc nó trong batch: bộ nhớ cập nhật ngay, còn bên đăng ký chạy một lần sau callback.
import { batch } from '@kkwaenggwari/restate';
function checkout() {
batch(() => {
useCart.set((cart) => ({ ...cart, items: [] }));
useOrder.set((order) => ({ ...order, status: 'paid' }));
});
// Subscribers run once, after both stores changed.
}Đăng ký bên ngoài React
subscribeSelector chỉ gọi bạn khi giá trị được chọn thay đổi, với cùng hàm so sánh tùy chọn.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Nối sự kiện bên ngoài
Đối số thứ hai của restate có thể là một updater. Nó chạy khi component hoặc bên đăng ký đầu tiên bắt đầu lắng nghe, và phần dọn dẹp chạy khi bên cuối cùng dừng lại, nên sự kiện trình duyệt, socket hay cảm biến chỉ được nối khi cần.
Dùng start() và stop() để điều khiển thủ công.
import { restate } from '@kkwaenggwari/restate';
// Listens while at least one component or subscriber uses the store.
export const useOnline = restate(true, ({ setState }) => {
const update = () => setState(navigator.onLine);
window.addEventListener('online', update);
window.addEventListener('offline', update);
update();
return () => {
window.removeEventListener('online', update);
window.removeEventListener('offline', update);
};
});