preactjs / signals

Manage state with style in every framework
https://preactjs.com/blog/introducing-signals/
MIT License
3.75k stars 91 forks source link

Update Array without re-render non-updated items #464

Closed Jeremy38100 closed 9 months ago

Jeremy38100 commented 9 months ago

Hello,

Here an example of simple code of an array in a signal. Is there a way to re-render only updated/new items in the array for performance optimisation.

import { render } from "preact";
import { signal } from "@preact/signals";

const arr = signal([{value: 1}]);

function Item({item}) {
    // This is logged for every items on Add
    console.log('render', item.value)
    return (<li>{item.value}</li>)
}

function TodoList() {
  const addItem = () => arr.value = [...arr.value, {value: Math.random()}]
  return (
    <>
      <button onClick={addItem}>Add</button>
      <ul>
        {arr.value.map(item => (<Item item={item} />))}
      </ul>
    </>
  );
}

render(<TodoList />, document.getElementById("app"));

REPL Playground

Thank you for your help,

Awesome work on this library ❤️

rschristian commented 9 months ago

Can you get away with an array of components, instead of an array of data?

import { render } from "preact";
import { signal } from "@preact/signals";

const arr = signal([<Item item={1} />]);

function Item({ item }) {
  console.log("render", item);
  return <li>{item}</li>;
}

function TodoList() {
  const addItem = () => (arr.value = [...arr.value, <Item item={Math.random()} />]);

  return (
    <>
      <button onClick={addItem}>Add</button>
      <ul>{arr.value}</ul>
    </>
  );
}

render(<TodoList />, document.getElementById("app"));
Jeremy38100 commented 9 months ago

Interesting! But I'm facing a case where I can not get away with an array of components instead of an array of data. I really need the array of data.

rschristian commented 9 months ago

Unfortunately I believe that's your only option.

Jeremy38100 commented 9 months ago

OK, thank you for your response and proposition !

rschristian commented 9 months ago

I was reminded of this today: https://gist.github.com/developit/af2a4488de152a84bff83e035bb8afc1

It's a bit more involved (not a built-in, gotta copy from a gist and perhaps therefore less than idiomatic), but should do what you need.