6.5Kпросмотров
21 апреля 2025 г.
Score: 7.2K
Шутка, которая вышла из под контроля Меня до сих пор бесит состояние вокруг стейт менеджеров в react. По факту, внутри react есть система управления состоянием, которая мне нравится. В ней заложены мощные концепции, которые хоть иногда не самые волшебные и простые, но зато надежные и защищают от многих выстрелов в колено. (Только важно знать, как работает замыкание) Например:
– Однонаправленный поток данных.
– Иммутабельность
– Банчинг Чтобы доказать эту идею нужен целый доклад 😉 Сейчас просто считайте это моей позицией Но, к сожалению, у локального React состояния есть важные минусы:
– Оно привязано к жизненному циклу реакта
– Оно привязано к структуре компонентов
– И, вроде, есть контекст для решения второй проблемы, но нет точечной подписки Эти проблемы нельзя игнорировать, и для комфортной работы нам приходится подключать стейт менеджеры. И нет бы просто взять то, что есть в React и просто решить проблемы. НЕЕЕТ, надо ввести кучу своих концепций, напридумывать всякие санки, саги, прокси, потоки, эффекты, эвенты.... 🫠 И вот нам приходится сначала учить React, потом стейт менеджер. А потом пытаться как-то натянуть одно на второе. --- Недавно, накануне первого апреля, я заглянул в исходники React и обнаружил там интересное: import * as React from "react"; const ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; const useState = ReactSharedInternals.H.useState Оказывается, реализация хуков в React – это динамическая штука. Значит их можно подпихнуть в эту переменную когда угодно и заменить реализацию. И тут у меня родился коварный план 😈 ХОЧУ КАК REACT, ТОЛЬКО ГЛОБАЛЬНО. А ЕЩЁ С ТОЧЕЧНОЙ ПОДПИСКОЙ. И в результате некоторого исследования получилось вот это: import { createGStore } from 'create-gstore';
import { useState } from 'react'; // Define a global state from a hook
const useGlobalCounter = createGStore(() => { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); const decrement = () => setCount(count - 1); return { count, increment, decrement };
}); function CounterButton() { const { count, increment } = useGlobalCounter(); return <button onClick={increment}>Count: {count}</button>;
} function CounterDisplay() { const count = useGlobalCounter(s => s.count); return <div>Current count: {count}</div>;
} Вы это видите?) Это обычные React хуки, которые работают как React хуки. Но только состояние привязано не к компоненту, а к глобальному хранилищу. Уже реализована поддержка: useState, useMemo, useCallback, useRef, useEffect, useLayoutEffect, useSyncExternalStore Короче, написал это. Посмотрел... А потом до меня дошло. Ведь огромное количество моих локальных хуков без изменений можно сделать глобальными. В том числе и библиотечные react-hook-form, react-query! И в этот момент я понял, что это уже имеет шансы стать не просто шуткой) ---
Вы уже можете установить себе и опробовать это. Благо, учить воообще ничего не надо. В доке есть куча примеров. Понятно, что это альфа версия, и могут быть проблемы, но уже сейчас выглядит как что-то супер простое и полезное! Очень люблю такие решения) Жду вашей обратной связи и ишьюсов на github) Очень интересно, что вы думаете! Документация:
https://evo-community.github.io/use-gstate/ github:
https://github.com/evo-community/use-gstate