import { shallowEqual } from 'react-redux' ; import { deepEqual } from '../utils/deepEqual' ; import { Model } from '../model/defineModel' ; import { toArgs } from '../utils/toArgs' ; import { useModelSelector } from '../redux/useSelector' ; /**
 * hooks新旧数据的对比方式：
 *
 * - `deepEqual`     深度对比，对比所有层级的内容。传递selector时默认使用。
 * - `shallowEqual`  浅对比，只比较对象第一层。传递多个模型但没有selector时默认使用。
 * - `strictEqual`   全等（===）对比。只传一个模型但没有selector时默认使用。
 */ export type Algorithm = 'strictEqual' | 'shallowEqual' | 'deepEqual' ; /**
 * * 获取模型的状态数据。
 * * 传入一个模型时，将返回该模型的状态。
 * * 传入多个模型时，则返回一个以模型名称为key、状态为value的大对象。
 * * 最后一个参数如果是**函数**，则为状态过滤函数，过滤函数的结果视为最终返回值。
 */ export function useModel < State extends object > ( model ) ; export function useModel < State extends object , T > ( model , selector , algorithm ? ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object > ( model1 , model2 ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , T > ( model1 , model2 , selector , algorithm ? ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object > ( model1 , model2 , model3 ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object , T > ( model1 , model2 , model3 , selector , algorithm ? ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object , Name4 extends string , State4 extends object > ( model1 , model2 , model3 , model4 ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object , Name4 extends string , State4 extends object , T > ( model1 , model2 , model3 , model4 , selector , algorithm ? ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object , Name4 extends string , State4 extends object , Name5 extends string , State5 extends object > ( model1 , model2 , model3 , model4 , model5 ) ; export function useModel < Name1 extends string , State1 extends object , Name2 extends string , State2 extends object , Name3 extends string , State3 extends object , Name4 extends string , State4 extends object , Name5 extends string , State5 extends object , T > ( model1 , model2 , model3 , model4 , model5 , selector , algorithm ? ) ; export function useModel ( ) { const args = toArgs ( arguments ) ; let algorithm = getLastElementType ( args ) === 'string' && args . pop ( ) ; const selector = getLastElementType ( args ) === 'function' && args . pop ( ) ; const models = args ; const modelsLength = models . length ; if ( ! algorithm ) { if ( selector ) { algorithm = 'deepEqual' ; } else if ( modelsLength > 1 ) { algorithm = 'shallowEqual' ; } else { algorithm = 'strictEqual' ; } } let memoResult = null ; let memoStates , currentStates , i , changed ; const reducerNames = [ ] ; for ( i = 0 ; i < modelsLength ; ++ i ) { reducerNames . push ( models [ i ] ! . name ) ; } return useModelSelector ( ( state ) => { currentStates = [ ] ; for ( i = 0 ; i < modelsLength ; ++ i ) { currentStates . push ( state [ reducerNames [ i ] ! ] ! ) ; } if ( memoResult !== null ) { if ( modelsLength === 1 ) { if ( currentStates [ 0 ] === memoStates [ 0 ] ) return memoResult ; } else { for ( i = modelsLength , changed = false ; i -- > 0 ; ) { if ( currentStates [ i ] !== memoStates [ i ] ) { changed = true ; break ; } } if ( ! changed ) return memoResult ; } } memoStates = currentStates ; if ( modelsLength === 1 ) { return ( memoResult = selector ? selector ( currentStates [ 0 ] ) : currentStates [ 0 ] ) ; } if ( selector ) { return ( memoResult = selector . apply ( null , currentStates ) ) ; } memoResult = { } ; for ( i = modelsLength ; i -- > 0 ; ) { memoResult [ reducerNames [ i ] ! ] = currentStates [ i ] ! ; } return memoResult ; } , compareFn [ algorithm ] ) ; } const compareFn = { deepEqual : deepEqual , shallowEqual : shallowEqual , strictEqual : void 0 , } ; const getLastElementType = ( args ) => { return args . length > 1 && typeof args [ args . length - 1 ] ; } ;