TeactN: Introduce stickToFirst
This commit is contained in:
parent
3d12a47866
commit
f894010a70
@ -14,6 +14,17 @@ import useUniqueId from '../../hooks/useUniqueId';
|
|||||||
|
|
||||||
export default React;
|
export default React;
|
||||||
|
|
||||||
|
interface Container {
|
||||||
|
mapStateToProps: MapStateToProps<any>;
|
||||||
|
activationFn?: ActivationFn<any>;
|
||||||
|
stuckTo?: any;
|
||||||
|
ownProps: Props;
|
||||||
|
mappedProps?: Props;
|
||||||
|
forceUpdate: Function;
|
||||||
|
DEBUG_updates: number;
|
||||||
|
DEBUG_componentName: string;
|
||||||
|
}
|
||||||
|
|
||||||
type GlobalState =
|
type GlobalState =
|
||||||
AnyLiteral
|
AnyLiteral
|
||||||
& { DEBUG_capturedId?: number };
|
& { DEBUG_capturedId?: number };
|
||||||
@ -36,7 +47,10 @@ type ActionHandler = (
|
|||||||
) => GlobalState | void | Promise<void>;
|
) => GlobalState | void | Promise<void>;
|
||||||
|
|
||||||
type MapStateToProps<OwnProps = undefined> = (global: GlobalState, ownProps: OwnProps) => AnyLiteral;
|
type MapStateToProps<OwnProps = undefined> = (global: GlobalState, ownProps: OwnProps) => AnyLiteral;
|
||||||
type ActivationFn<OwnProps = undefined> = (global: GlobalState, ownProps: OwnProps) => boolean;
|
type StickToFirstFn = (value: any) => boolean;
|
||||||
|
type ActivationFn<OwnProps = undefined> = (
|
||||||
|
global: GlobalState, ownProps: OwnProps, stickToFirst: StickToFirstFn,
|
||||||
|
) => boolean;
|
||||||
|
|
||||||
let currentGlobal = {} as GlobalState;
|
let currentGlobal = {} as GlobalState;
|
||||||
|
|
||||||
@ -50,15 +64,7 @@ const DEBUG_releaseCapturedIdThrottled = throttleWithTickEnd(() => {
|
|||||||
const actionHandlers: Record<string, ActionHandler[]> = {};
|
const actionHandlers: Record<string, ActionHandler[]> = {};
|
||||||
const callbacks: Function[] = [updateContainers];
|
const callbacks: Function[] = [updateContainers];
|
||||||
const actions = {} as Actions;
|
const actions = {} as Actions;
|
||||||
const containers = new Map<string, {
|
const containers = new Map<string, Container>();
|
||||||
mapStateToProps: MapStateToProps<any>;
|
|
||||||
activationFn?: ActivationFn<any>;
|
|
||||||
ownProps: Props;
|
|
||||||
mappedProps?: Props;
|
|
||||||
forceUpdate: Function;
|
|
||||||
DEBUG_updates: number;
|
|
||||||
DEBUG_componentName: string;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
const runCallbacksThrottled = throttleWithTickEnd(runCallbacks);
|
const runCallbacksThrottled = throttleWithTickEnd(runCallbacks);
|
||||||
|
|
||||||
@ -161,10 +167,10 @@ function updateContainers() {
|
|||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
for (const container of containers.values()) {
|
for (const container of containers.values()) {
|
||||||
const {
|
const {
|
||||||
mapStateToProps, activationFn, ownProps, mappedProps, forceUpdate,
|
mapStateToProps, ownProps, mappedProps, forceUpdate,
|
||||||
} = container;
|
} = container;
|
||||||
|
|
||||||
if (activationFn && !activationFn(currentGlobal, ownProps)) {
|
if (!activateContainer(container, currentGlobal, ownProps)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +272,7 @@ export function withGlobal<OwnProps extends AnyLiteral>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!container.mappedProps || (
|
if (!container.mappedProps || (
|
||||||
!arePropsShallowEqual(container.ownProps, props)
|
!arePropsShallowEqual(container.ownProps, props) && activateContainer(container, currentGlobal, props)
|
||||||
&& (!activationFn || activationFn(currentGlobal, props))
|
|
||||||
)) {
|
)) {
|
||||||
try {
|
try {
|
||||||
container.mappedProps = mapStateToProps(currentGlobal, props);
|
container.mappedProps = mapStateToProps(currentGlobal, props);
|
||||||
@ -288,6 +293,21 @@ export function withGlobal<OwnProps extends AnyLiteral>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function activateContainer(container: Container, global: GlobalState, props: Props) {
|
||||||
|
const { activationFn, stuckTo } = container;
|
||||||
|
if (!activationFn) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return activationFn(global, props, (stickTo: any) => {
|
||||||
|
if (stickTo && !stuckTo) {
|
||||||
|
container.stuckTo = stickTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stickTo && (!stuckTo || stuckTo === stickTo);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function typify<
|
export function typify<
|
||||||
ProjectGlobalState,
|
ProjectGlobalState,
|
||||||
ActionPayloads,
|
ActionPayloads,
|
||||||
@ -322,7 +342,7 @@ export function typify<
|
|||||||
) => void,
|
) => void,
|
||||||
withGlobal: withGlobal as <OwnProps extends AnyLiteral>(
|
withGlobal: withGlobal as <OwnProps extends AnyLiteral>(
|
||||||
mapStateToProps: (global: ProjectGlobalState, ownProps: OwnProps) => AnyLiteral,
|
mapStateToProps: (global: ProjectGlobalState, ownProps: OwnProps) => AnyLiteral,
|
||||||
activationFn?: (global: ProjectGlobalState, ownProps: OwnProps) => boolean,
|
activationFn?: (global: ProjectGlobalState, ownProps: OwnProps, stickToFirst: StickToFirstFn) => boolean,
|
||||||
) => (Component: FC) => FC<OwnProps>,
|
) => (Component: FC) => FC<OwnProps>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user