import noop from '@tinkoff/utils/function/noop' ; import { useReducer , useRef } from 'react' ; import type { Reducer } from '../../createReducer/createReducer.h' ; import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect' ; import { useConsumerContext } from './useConsumerContext' ; export function useStore < S > ( reducer ) { const context = useConsumerContext ( ) ; const reducerRef = useRef ( reducer ) ; const addedReducerRef = useRef < string | null > ( null ) ; const unsubscribeRef = useRef < Function > ( noop ) ; const [ , forceRender ] = useReducer ( ( s ) => s + 1 , 0 ) ; if ( ! context . hasStore ( reducer ) ) { context . registerStore ( reducer ) ; addedReducerRef . current = reducer . storeName ; } const stateRef = useRef < S > ( context . getState ( reducer ) ) ; useIsomorphicLayoutEffect ( ( ) => { const subscribe = ( updatedState ) => { if ( stateRef . current !== updatedState ) { stateRef . current = updatedState ; forceRender ( ) ; } } ; subscribe ( context . getState ( reducer ) ) ; unsubscribeRef . current = context . subscribe ( reducer , subscribe ) ; reducerRef . current = reducer ; return ( ) => { unsubscribeRef . current ( ) ; if ( addedReducerRef . current ) { context . unregisterStore ( reducerRef . current ) ; addedReducerRef . current = null ; } } ; } , [ reducer , context ] ) ; return stateRef . current as S ; }