useList()
Syntax: const [list, delta] = useList(initialListValue)
Example: const [list, delta] = useList([1, 2, 3])
The useList()
hook is an optimized version of the useState()
hook, but exclusvely for arrays. Instead of returning state
and setState
, it returns list
and delta
. list
is a mutable value that you can update like a variable, and delta
is a payload that you can pass into virtual nodes.
import { createRoot, useList } from 'million/react';
function App() {
const [list, delta] = useList([]);
return (
<>
<button
onClick={() => {
list.push(list.length + 1);
}}
>
Add
</button>
<ul delta={delta}>
{list.map((item) => (
<li>{item}</li>
))}
</ul>
</>
);
}
createRoot(document.body).render(<App />);
useList
leverages a highly reactive data structure and exports Delta to update the Virtual DOM. This makes it possible to update the DOM without having to go through traditional Virtual DOM diffing.
Below is a comparison chart of the insane performance useList
(through Delta) has, making it as fast as Solid.js and Svelte!
React uses the Virtual DOM, and it can get REALLY slow when there's a lot of children, even with keyed nodes. The reason why is React isn't actually aware of the state during rendering, leading to a lot of unnecessary work.
TL;DR: The bottleneck is diffing.
Million now supports a new Delta rendering, which is a new reactive primitive! It uses a Proxy to capture changes to the state and calculate the necessary DOM manipulations.
This way, we bypass diffing altogether, removing the bottleneck: