Задать вопрос
@Boris009

Как реализовать свой простой стейт менеджер для реакта?

На чём базируются стейт менеджеры реакта?
Как реализовать свой, чтобы понять основной принцип работы редакса и мобикса?
  • Вопрос задан
  • 158 просмотров
Подписаться 2 Средний 2 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик
    10 месяцев
    Далее
Решения вопроса 1
В догонку к комментарию:
Сама имплементация
import { useState } from 'react'

class Signal<T> {
    #value: T
    #dispatchers: Set<React.Dispatch<React.SetStateAction<T>>> = new Set()
    constructor(value: T){
        this.#value = value
    }
    get current(): T {
        return this.#value
    }
    set current(value: T){
        if(this.#value !== value){
            this.#value = value
            for(const dispatcher of this.#dispatchers){
                dispatcher(this.#value)
            }
        }
    }
    subscribe(dispatcher: React.Dispatch<React.SetStateAction<T>>): void {
        if(!(this.#dispatchers.has(dispatcher))){
            this.#dispatchers.add(dispatcher)
        }
    }
}

const createSignal = <T>(value: T): Signal<T> => new Signal(value)

const useSignal = <T>(signal: Signal<T>): Signal<T> => {
    const [, dispatcher] = useState(signal.current)
    signal.subscribe(dispatcher)
    return signal
}

export { createSignal, useSignal }

Экспорт сигналов
import { createSignal } from '../lib/signals.ts'

export const counter = createSignal(0)

Компонент, который импортирует и использует сигнал
import { useSignal } from '../lib/signals.ts'
import { counter } from './shared_signals.ts'

export const Button = () => {
    const _counter = useSignal(counter)
    return (
        <button onClick={ () => ++_counter.current }>
            Count is { _counter.current }
        </button>
    )
}

Клиентский скрипт
import { hydrateRoot } from 'react-dom/client'

import { Layout } from './Layout.tsx'
import { Button } from './Button.tsx'

hydrateRoot(
    document,
    <Layout>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>
    </Layout>
)

При клике на любую кнопку - используется сигнал, который ты создаёшь один раз, экспортируешь его и можешь использовать где угодно, в любом компоненте. Примерно так эти стейт-менеджеры и работают. Они держат состояние/состояния вне компонентов. А работает это из-за самой природы импортов/экспортов. Если ты экспортируешь, например так: export const obj = { count: 0 }, а затем импортируешь этот obj в другом модуле и увеличиваешь count - то этот count будет увеличен в контексте всех модулей, которые его импортировали, либо будут импортировать.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽