restate / v1.0.0
Berlangganan hanya pada yang Anda butuhkan
Pilih bagian store yang menjadi ketergantungan tiap komponen, bandingkan objek dengan shallow, kelompokkan perubahan dengan batch, dan sambungkan event dari luar.
Di halaman ini
Berikan selectorCobaMemilih beberapa field dengan shallowPerbandingan sendiriMengelompokkan perubahan dengan batchBerlangganan di luar ReactMenyambungkan event dari luarBerikan selector
Panggil hook dengan fungsi yang memilih apa yang dibutuhkan komponen. Setelah setiap perubahan, restate menjalankan selector dan membandingkan hasilnya dengan yang sebelumnya menggunakan Object.is. Jika sama, komponen tidak dirender.
Kartu berubah. Apakah ItemCount dirender?
Tidak. Fungsi selector-nya masih mengembalikan jumlah produk yang sama, jadi pilihannya sama dan React tidak diminta merender.
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>;
}Coba
Ubah field dan perhatikan penghitung render. Matikan shallow untuk melihat selector yang mengembalikan objek baru setiap kali.
Menyiapkan contoh…
Memilih beberapa field dengan shallow
Saat selector membangun objek, ia mengembalikan objek baru setiap kali, sehingga Object.is selalu melihat perubahan. Berikan shallow sebagai argumen kedua: ia membandingkan field milik objek sedalam satu tingkat.
shallow juga membandingkan elemen array, Map, dan Set sedalam satu tingkat.
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>
);
}Perbandingan sendiri
Fungsi (left, right) => boolean apa pun bisa menjadi argumen kedua. Gunakan saat shallow tidak cukup, misalnya untuk membandingkan daftar berdasarkan id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Mengelompokkan perubahan dengan batch
Setiap set langsung memberi tahu pelanggan. Saat satu tindakan mengubah beberapa store, bungkus dengan batch: memori langsung diperbarui, dan pelanggan berjalan sekali setelah 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.
}Berlangganan di luar React
subscribeSelector memanggil Anda hanya saat nilai yang dipilih berubah, dengan fungsi pembanding opsional yang sama.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Menyambungkan event dari luar
Argumen kedua restate bisa berupa updater. Ia berjalan saat komponen atau pelanggan pertama mulai mendengarkan, dan pembersihannya berjalan saat yang terakhir berhenti, sehingga event browser, socket, atau sensor hanya tersambung selama dibutuhkan.
Gunakan start() dan stop() untuk kendali manual.
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);
};
});