#reactjs #apollo-client
#реагирует на #аполлон-клиент
Вопрос:
Реактивные переменные имеют большой смысл при хранении простых скалярных значений, но если вам нужно иметь дело с более сложным состоянием (скажем, ID-gt;object
картой), вы столкнетесь с проблемами производительности рендеринга. Проблема в том, что реактивные переменные фактически неизменяемы: вы не можете просто изменить какое-то под-свойство переменной и ожидать, что оно будет реагировать правильно; вам нужно указать совершенно новое значение для переменной. Но тогда каждый компонент, который прослушивает эту переменную, будет перенаправляться, даже если многим из них может быть наплевать на это конкретное свойство.
Я поясню это на примере. Допустим, у меня есть эта реактивная переменная:
const itemsMapVar = makeVar({ item1: { text: "Text 1" }, item2: { text: "Text 2" } })
И я представляю список элементов, каждый из которых выглядит следующим образом:
const ListItem = (props) =gt; { const item = useReactiveVar(itemsMapVar)[props.id]; return lt;divgt;{item.text}lt;/divgt; }
Предположим, я изменю текст для пункта 1:
itemsMapVar({ ...itemsMapVar(), item1: { text: 'New text' } })
Теперь и пункт 1, и пункт 2 будут повторяться, потому что они оба слушают itemsMapVar
. Это может не быть проблемой в этом тривиальном примере, но если есть длинный список элементов с большим количеством DOM, это будет проблемой. Существует ли устоявшаяся передовая практика для решения этой проблемы?
Некоторые варианты, которые я рассмотрел:
- Используйте другую библиотеку состояний клиента. Что-то вроде Redux или MobX легко решает такого рода проблемы. Одним большим недостатком является то, что я не могу использовать это состояние как часть реактивного запроса GraphQL, и, вероятно, именно поэтому я в первую очередь использую Apollo.
- Поместите компонент обертки
lt;ListItemgt;
, содержащийuseReactiveVar
крючок, и извлеките свойство, которое меня интересует. ТогдаReact.memo
включениеListItem
предотвратит его ненужный рендеринг. Это не страшно; но вы все равно визуализируете O(N) элементов, но это всего лишь легкие элементы обертки. И это кажется довольно многословным и неуклюжим для того, что кажется обычной проблемой при работе с состоянием клиента. - Придумайте какую-нибудь новую версию
useReactiveVar
, которая знает, как выбрать нужную вам часть состояния, похожую на ReduxuseSelector
. (Существует ли такая вещь уже?)