I have a datatable in react, and I'm trying to make it more lightweight so it is usable with larger datasets on weaker devices. I'm experimenting with a few things and I heard good things about preact/signals, but the examples I see are very basic use-cases where I'm very doubtful about the performance gains. I see 2 kinds of examples.
import { signal } from "@preact/signals-react";
const count = signal(0);
function Counter() {
return (
<div>
<p>Count: {count}</p>
<button onClick={() => count.value++}>click me</button>
</div>
);
}
import { signal } from "@preact/signals";
const todos = signal([
{ text: "Buy groceries" },
{ text: "Walk the dog" },
]);
What I want to achieve is that I have a list of elements with many properties (all have the same type) where I could create a virtualized list with something like react-window. I can "subscribe" to only fragments of the state, so the app is only rerendering what is absolutely necessary.
So the list could be something like this where you can edit certain fields (which are not calculated)
First Name | Last Name | Full Name | Phone | |
---|---|---|---|---|
Lorine | Rhoda | Lorine Rhoda | ... | ... |
Jaylynn | Heaven | Jaylynn Heaven | ... | ... |
Marigold | Fox | Marigold Fox | ... | ... |
Is it possible to make this list in a way that modifying the last name of a person only rerenders that specific row's last name and full name? (or better yet, does not even rerender the cell, just changes the string)
How would I make my signal "granularly subscribable and modifiable"?
It's quite simple actually: signals can be nested.
import { signal } from '@preact/signals-react';
const person = signal({
firstName: signal('John'),
lastName: signal('Doe'),
});
function App() {
console.log('component rerender');
return (
<div>
<p>{person.value.firstName}</p>
<p>{person.value.lastName}</p>
<input onInput={(e) => (person.value.firstName.value = e.target.value)} />
</div>
);
}
You can edit the first name using that input and the full component will not rerender; instead, just the text for the firstName
will update.
For your table, you'd do something similar, have a signal wrapping an array in which each record uses signals for its individual properties.