TGViewer
Заметки про React Заметки про React @ru_react_notes · 3.44K subscribers
Post #532 4.1K
Реактивность – это легко

Стандартный useContext заставляет обновляться все компоненты-потребители, даже если им не нужна изменившаяся часть состояния. Это приводит к лишним ре-рендерам, особенно в больших компонентах вроде таблиц или списков.

Автор статьи столкнулся с этим в MUI X Data Grid: клик по одной ячейке вызывал ре-рендер всех остальных. Решение — точечная подписка через селекторы

Вместо того, чтобы хранить состояние в useState и передавать его через Context, можно использовать внешний Store и специальный хук useSelector. Идея проста:

🔴 Store — это обычный класс, который хранит состояние, умеет подписывать на обновления (subscribe) и уведомлять подписчиков, когда данные изменились (update). Он живёт вне рендера React.

🔴 useSelector(store, selectorFn) — кастомный хук, который принимает store и функцию-селектор. Селектор — это функция, которая из всего объекта состояния достает только нужный компонентa фрагмент данных (например, `state => state.focus === index`).

Хук подписывается на store и вызывает локальный ре-рендер только тогда, когда возвращаемое селектором значение изменилось.

Пример кода:


const Context = createContext();

export function Grid() {
const [store] = useState(() => new Store({ focus: 0 }));

return (
<Context.Provider value={store}>
{Array.from({ length: 50 }).map((_, i) => (
<Cell index={i} />
))}
</Context.Provider>
);
}

const selectors = {
isFocus: (state, index) => state.focus === index,
};

function Cell({ index }) {
const store = useContext(Context);
const focus = useSelector(store, selectors.isFocus, index);

return (
<button
ref={ref}
onClick={() => store.update({ ...store.state, focus: index })}
className={clsx({ focus })}
>
{index}
</button>
);
};


Такой подход позволяет обновлять только те компоненты, чьи данные действительно изменились, и часто избавляет от необходимости оборачивать всё в React.memo.

https://romgrk.com/posts/reactivity-is-easy/
Romgrk Reactivity is easy romgrk's personal blog
  • 👎 22
  • 👍 7
  • ❤ 3
More from @ru_react_notes
  1. Jun 17, 2025Остерегайтесь скрытых проблем при работе с search params Типо-безопасность — это только ве…
  2. Jun 4, 2025Почему Error Boundary, а не просто try/catch для компонентов В React нельзя использовать t…
  3. May 29, 2025Анонс TypeScript Native Вышла превью версия TypeScript написанная на Go. Ее можно установи…
  4. May 27, 2025Управление фокусом в React с помощью flushSync Установить фокус на инпуте сразу в React мо…
  5. May 15, 2025TanStack DB TanStack представила новую библиотеку – TanStack DB – реактивный клиентский ст…
  6. May 13, 2025Родители и владельцы в React: провайдеры контекста Джулс Блом в своем блоге написала про т…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →