Но как показалось, React.memo можно было избежать.
зачем? здесь оно в самый раз.
а вообще у тебя какая-то хрень в нейминге. По идее, компонент Position должен быть для каждого элемента массива positions. А то что у тебя называется Position, должно называться Dish, и тоже быть memo
т.е. так:
{positions.map(({ id, name, ref, dishes }) => <Position ... />)}
export const Position = memo(({ ..., dishes, ... }) => {
.........
{dishes.map((item) => <Dish ... />}
.....
});
тогда при изменении чего-то, например, внутри блюда, будет перерендер компонента со списком позиций, перерендер одной позиции с блюдом, и перерендер блюда.
Это минимум для иммутабельного стейта. Если хочешь совсем упороться и выкинуть перерендер списка, то mobx в помощь.