List of items to render
-----------------------

Given a list of items (coming from the server):

```
const itemsFromServer = {
  "1": {
    id: "1",
    value: "test"
  },
  "2": {
    id: "2",
    value: "another row"
  }
};

```

Function component for each item
--------------------------------

We want to render each item, but only when necessary and something changes:

```
const Item = React.memo(function Item({ id, value, onChange, onSave }) {
  console.log("render", id);

  return (
    <li>
      <input
        value={value}
        onChange={event => onChange(id, event.target.value)}
      />
      <button onClick={() => onSave(id)}>Save</button>
    </li>
  );
});

```

ItemList function component with a `handleSave` function that needs to be memoized.
-----------------------------------------------------------------------------------

And there is a possibility to save each individual item:

```
function ItemList() {
  const [items, setItems] = useState(itemsFromServer);

  const handleChange = useCallback(
    function handleChange(id, value) {
      setItems(currentItems => {
        return {
          ...currentItems,
          [id]: {
            ...currentItems[id],
            value
          }
        };
      });
    },
    [setItems]
  );

  async function handleSave(id) {
    const item = items[id];

    if (item.value.length < 5) {
      alert("Incorrect length.");
      return;
    }

    await save(item);

    alert("Save done :)");
  }

  return (
    <ul>
      {Object.values(items).map(item => (
        <Item
          key={item.id}
          id={item.id}
          value={item.value}
          onChange={handleChange}
          onSave={handleSave}
        />
      ))}
    </ul>
  );
}

```

How to prevent unnecessary re-renders of each `Item` when only one item changes?

Currently on each render a new `handleSave` function is created. When using `useCallback` the `items` object is included in the dependency list.

Possible solutions
------------------

1. Pass `value` as parameter to `handleSave`, thus removing the `items` object from the dependency list of `handleSave`. In this example that would be a decent solution, but for multiple reasons it's not preferred in the real life scenario (eg. lots more parameters etc.).
2. Use a separate component `ItemWrapper` where the `handleSave` function can be memoized.

```
function ItemWrapper({ item, onChange, onSave }) {
  const memoizedOnSave = useCallback(onSave, [item]);

  return (
    <Item
      id={item.id}
      value={item.value}
      onChange={onChange}
      onSave={memoizedOnSave}
    />
  );
}

```

3. With the `useRef()` hook, on each change to `items` write it to the ref and read `items` from the ref inside the `handleSave` function.
4. Keep a variable `idToSave` in the state. Set this on save. Then trigger the save function with `useEffect(() => { /* save */ }, [idToSave])`. "Reactively".

Question
--------

All of the solutions above seem not ideal to me. **Are there any other ways to prevent creating a new `handleSave` function on each render for each `Item`, thus preventing unnecessary re-renders?** If not, is there a preferred way to do this?

CodeSandbox: <https://codesandbox.io/s/wonderful-tesla-9wcph?file=/src/App.js>