Commit 3fe0ceb4 authored by Shen Chang's avatar Shen Chang

refactor(src): Rewrite with typescript, Added include and exclude

parent a089fc4a
......@@ -892,6 +892,20 @@
"to-fast-properties": "^2.0.0"
}
},
"@types/hoist-non-react-statics": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.0.1.tgz",
"integrity": "sha512-3wTz66vV+WatOAjMST+hKCmo01KYPFgnsu+QeLcn0FuwPCoymX6aj1a4RvFCdVsfh2m0hfTPhE/zTv4M28ho1Q==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/js-md5": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@types/js-md5/-/js-md5-0.4.2.tgz",
"integrity": "sha512-FUPoQkpQTzA5wz9ebrdVRjsjQsFehr+cW1CVhLcI2UwD/SO/4NHPO1esrXPPbx7ux762U0POmWFSrUjQq2ophw=="
},
"@types/node": {
"version": "10.12.29",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.29.tgz",
......@@ -914,6 +928,15 @@
"csstype": "^2.2.0"
}
},
"@types/react-dom": {
"version": "16.8.2",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.8.2.tgz",
"integrity": "sha512-MX7n1wq3G/De15RGAAqnmidzhr2Y9O/ClxPxyqaNg96pGyeXUYPSvujgzEVpLo9oIP4Wn1UETl+rxTN02KEpBw==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@webassemblyjs/ast": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
......
......@@ -2,42 +2,50 @@ import React from 'react';
import ReactDOM from 'react-dom';
import noop from '../utils/noop';
export default class Comment extends React.PureComponent {
parentNode = null;
currentNode = null;
commentNode = null;
content = null;
componentDidMount() {
const node = ReactDOM.findDOMNode(this);
interface IReactCommentProps {
onLoaded: () => void;
}
class ReactComment extends React.PureComponent<IReactCommentProps> {
public static defaultProps = {
onLoaded: noop,
};
private parentNode: Node;
private currentNode: Element;
private commentNode: Comment;
private content: string;
public componentDidMount() {
const node = ReactDOM.findDOMNode(this) as Element;
const commentNode = this.createComment();
this.commentNode = commentNode;
this.currentNode = node;
this.parentNode = node.parentNode;
this.parentNode = node.parentNode as Node;
this.parentNode.replaceChild(commentNode, node);
ReactDOM.unmountComponentAtNode(node);
this.props.onLoaded();
}
componentWillUnmount() {
public componentWillUnmount() {
this.parentNode.replaceChild(this.currentNode, this.commentNode);
}
createComment() {
private createComment() {
let content = this.props.children;
if (typeof content !== 'string') {
content = '';
}
content = content.trim();
this.content = content;
return document.createComment(content);
this.content = (content as string).trim();
return document.createComment(this.content);
}
render() {
public render() {
return <div />;
}
}
Comment.defaultProps = {
onLoaded: noop,
};
\ No newline at end of file
export default ReactComment;
import React from 'react';
import Comment from './Comment';
import {LIFECYCLE, ICache, ICacheItem} from './Provider';
import findDOMNodeByFiberNode from '../utils/findDOMNodeByFiberNode';
import createUniqueIdentification from '../utils/createUniqueIdentification';
export const LIFECYCLE = {
MOUNTED: 0,
UPDATING: 1,
UNMOUNTED: 2,
};
interface IConsumerProps {
children: React.ReactNode;
identification: string;
keepAlive: boolean;
cache: ICache;
setCache: (identification: string, value: ICacheItem) => void;
unactivate: (identification: string) => void;
}
class Consumer extends React.PureComponent<IConsumerProps> {
private renderElement: HTMLElement;
class Consumer extends React.PureComponent {
renderElement = null;
identification = this.props.identification;
private identification: string = this.props.identification;
// This attribute is designed to prevent duplicates of the identification of KeepAlive components.
key = createUniqueIdentification();
private key: string = createUniqueIdentification();
constructor(props) {
super(props);
constructor(props: IConsumerProps, ...args: any) {
super(props, ...args);
const {cache, setCache, children} = props;
if (!cache || !setCache) {
throw new Error('<KeepAlive> component must be in the <Provider> component.');
......@@ -26,14 +30,14 @@ class Consumer extends React.PureComponent {
React.Children.only(children);
}
componentDidMount() {
public componentDidMount() {
const {
setCache,
children,
keepAlive,
} = this.props;
const {_reactInternalFiber} = this;
this.renderElement = findDOMNodeByFiberNode(_reactInternalFiber);
const {_reactInternalFiber} = this as any;
this.renderElement = findDOMNodeByFiberNode(_reactInternalFiber) as HTMLElement;
setCache(this.identification, {
children,
keepAlive,
......@@ -44,9 +48,9 @@ class Consumer extends React.PureComponent {
});
}
componentDidUpdate() {
public componentDidUpdate() {
const {
setCache,
setCache,
children,
keepAlive,
} = this.props;
......@@ -57,15 +61,15 @@ class Consumer extends React.PureComponent {
});
}
componentWillUnmount() {
public componentWillUnmount() {
const {unactivate} = this.props;
unactivate(this.identification);
}
render() {
public render() {
const {identification} = this;
return <Comment>{identification}</Comment>;
}
}
export default Consumer;
\ No newline at end of file
export default Consumer;
import React from 'react';
import ReactDOM from 'react-dom';
import Comment from './Comment';
import {LIFECYCLE} from './Consumer';
import KeepAliveContext from '../contexts/KeepAliveContext';
import createEventEmitter from '../utils/createEventEmitter';
import createUniqueIdentification from '../utils/createUniqueIdentification';
......@@ -10,79 +9,119 @@ import createStoreElement from '../utils/createStoreElement';
export const keepAliveProviderTypeName = 'KeepAliveProvider';
export const START_MOUNTING_DOM = 'startMountingDOM';
export enum LIFECYCLE {
MOUNTED,
UPDATING,
UNMOUNTED,
}
export interface ICacheItem {
children: React.ReactNode;
keepAlive: boolean;
lifecycle: LIFECYCLE;
key?: string | null;
renderElement?: HTMLElement;
activated?: boolean;
ifStillActivate?: boolean;
reactivate?: () => void;
}
export interface ICache {
[key: string]: ICacheItem;
}
export interface IKeepAliveProviderImpl {
storeElement: HTMLElement;
cache: ICache;
keys: string[];
eventEmitter: any;
existed: boolean;
providerIdentification: string;
setCache: (identification: string, value: ICacheItem) => void;
unactivate: (identification: string) => void;
isExisted: () => boolean;
}
export interface IKeepAliveProviderProps {
include?: string | string[] | RegExp;
exclude?: string | string[] | RegExp;
}
// TODO: include max exclude
export default class KeepAliveProvider extends React.PureComponent {
storeElement = createStoreElement();
export default class KeepAliveProvider extends React.PureComponent<IKeepAliveProviderProps> implements IKeepAliveProviderImpl {
public static displayName = keepAliveProviderTypeName;
public storeElement = createStoreElement();
// Sometimes data that changes with setState cannot be synchronized, so force refresh
cache = Object.create(null);
public cache: ICache = Object.create(null);
keys = [];
public keys: string[] = [];
eventEmitter = createEventEmitter();
public eventEmitter = createEventEmitter();
existed = true;
public existed: boolean = true;
needRerender = false;
private needRerender: boolean = false;
providerIdentification = createUniqueIdentification();
public providerIdentification: string = createUniqueIdentification();
componentDidUpdate() {
public componentDidUpdate() {
if (this.needRerender) {
this.needRerender = false;
this.forceUpdate();
}
}
componentWillUnmount() {
public componentWillUnmount() {
this.eventEmitter.clear();
this.existed = false;
document.body.removeChild(this.storeElement);
}
isExisted = () => {
public isExisted = () => {
return this.existed;
};
}
setCache = (identification, value) => {
public setCache = (identification: string, value: ICacheItem) => {
const {cache, keys} = this;
const {key} = cache[identification] || {};
if (!key) {
keys.push(identification);
// this.shiftKey();
}
if (key && value.key && key !== value.key) {
const currentCache = cache[identification];
const key = currentCache && currentCache.key;
if (key && value.key && key !== (value.key as unknown)) {
throw new Error('Cached components have duplicates.');
}
if (!currentCache) {
keys.push(identification);
}
this.cache[identification] = {
...cache[identification],
...currentCache,
...value,
};
this.forceUpdate();
};
getMax = () => {
return this.props.max ? parseInt(this.props.max) : null;
};
shiftKey = () => {
const max = this.getMax();
const {keys, cache} = this;
if (!max || keys.length <= max) {
return;
}
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const currentCache = cache[key];
if (currentCache && !currentCache.activated) {
keys.splice(i, 1);
delete cache[key];
return;
}
}
}
unactivate = identification => {
// private getMax = () => {
// return this.props.max ? parseInt(this.props.max) : null;
// }
// private shiftKey = () => {
// const max = this.getMax();
// const {keys, cache} = this;
// if (!max || keys.length <= max) {
// return;
// }
// for (let i = 0; i < keys.length; i++) {
// const key = keys[i];
// const currentCache = cache[key];
// if (currentCache && !currentCache.activated) {
// keys.splice(i, 1);
// delete cache[key];
// return;
// }
// }
// }
public unactivate = (identification: string) => {
const {cache} = this;
this.cache[identification] = {
...cache[identification],
......@@ -91,36 +130,35 @@ export default class KeepAliveProvider extends React.PureComponent {
lifecycle: LIFECYCLE.UNMOUNTED,
};
this.forceUpdate();
};
}
startMountingDOM = identification => {
private startMountingDOM = (identification: string) => {
this.eventEmitter.emit([identification, START_MOUNTING_DOM]);
};
}
render() {
public render() {
const {
cache,
keys,
providerIdentification,
isExisted,
setCache,
unactivate,
shiftKey,
storeElement,
eventEmitter,
} = this;
const {
children,
children: innerChildren,
include,
exclude,
} = this.props;
return (
<KeepAliveContext.Provider
<KeepAliveContext.Provider
value={{
cache,
providerIdentification,
isExisted,
setCache,
shiftKey,
unactivate,
storeElement,
eventEmitter,
......@@ -129,19 +167,15 @@ export default class KeepAliveProvider extends React.PureComponent {
}}
>
<React.Fragment>
{children}
{innerChildren}
{
Object.entries(cache).map((
[
identification,
{
keepAlive,
children,
lifecycle,
},
],
) => {
keys.map(identification => {
const currentCache = cache[identification];
const {
keepAlive,
children,
lifecycle,
} = currentCache;
let cacheChildren = children;
if (lifecycle === LIFECYCLE.MOUNTED && !keepAlive) {
// If the cache was last enabled, then the components of this keepAlive package are used,
......@@ -162,7 +196,7 @@ export default class KeepAliveProvider extends React.PureComponent {
<React.Fragment>
<Comment>{identification}</Comment>
{cacheChildren}
<Comment
<Comment
onLoaded={() => this.startMountingDOM(identification)}
>{identification}</Comment>
</React.Fragment>
......@@ -177,4 +211,4 @@ export default class KeepAliveProvider extends React.PureComponent {
</KeepAliveContext.Provider>
);
}
}
\ No newline at end of file
}
import React from 'react';
const WithKeepAliveContext = React.createContext();
export default WithKeepAliveContext;
\ No newline at end of file
import React from 'react';
const WithKeepAliveContext = React.createContext({});
export default WithKeepAliveContext;
import React from 'react';
const KeepAliveContext = React.createContext();
export default KeepAliveContext;
\ No newline at end of file
import React from 'react';
const KeepAliveContext = React.createContext({});
export default KeepAliveContext;
......@@ -6,4 +6,4 @@ export {
Provider,
keepAlive,
bindLifecycle,
};
\ No newline at end of file
};
This diff is collapsed.
......@@ -5,7 +5,7 @@ import {COMMAND} from './keepAlive';
import withIdentificationContextConsumer from './withIdentificationContextConsumer';
import getDisplayName from './getDisplayName';
export default function bindLifecycle(Component) {
export default function bindLifecycle<P = any>(Component: React.ComponentType<P>) {
const {
componentDidMount = noop,
componentDidUpdate = noop,
......@@ -30,8 +30,8 @@ export default function bindLifecycle(Component) {
componentDidActivate.call(this);
}
eventEmitter.on(
[identification, COMMAND.ACTIVATE],
this._bindActivate = () => this._needActivate = true,
[identification, COMMAND.ACTIVATE],
this._bindActivate = () => this._needActivate = true,
true,
);
eventEmitter.on(
......@@ -84,11 +84,11 @@ export default function bindLifecycle(Component) {
const NewComponent = withIdentificationContextConsumer(
({
forwardRef,
forwardRef,
_identificationContextProps: {
identification,
eventEmitter,
activated,
identification,
eventEmitter,
activated,
keepAlive,
},
...wrapperProps
......@@ -105,11 +105,11 @@ export default function bindLifecycle(Component) {
activated,
}}
/>
)
)
: null
),
);
NewComponent.displayName = `bindLifecycle(${getDisplayName(Component)})`;
return hoistNonReactStatics(
React.forwardRef((props, ref) => (
......@@ -117,4 +117,4 @@ export default function bindLifecycle(Component) {
)),
Component,
);
};
}
const NODE_TYPES = {
ELEMENT: 1,
COMMENT: 8,
};
enum NODE_TYPES {
ELEMENT = 1,
COMMENT = 8,
}
function findElementsBetweenComments(node, identification) {
function findElementsBetweenComments(node: Node, identification: string): Node[] {
const elements = [];
const childNodes = node.childNodes;
const childNodes = node.childNodes as any;
let startCommentExist = false;
for (let i = 0; i < childNodes.length; i++) {
const child = childNodes[i];
for (const child of childNodes) {
if (
child.nodeType === NODE_TYPES.COMMENT &&
child.nodeValue.trim() === identification &&
child.nodeValue.trim() === identification &&
!startCommentExist
) {
startCommentExist = true;
......@@ -24,10 +23,9 @@ function findElementsBetweenComments(node, identification) {
return elements;
}
function findComment(node, identification) {
const childNodes = node.childNodes;
for (let i = 0; i < childNodes.length; i++) {
const child = childNodes[i];
function findComment(node: Node, identification: string): Node | undefined {
const childNodes = node.childNodes as any;
for (const child of childNodes) {
if (
child.nodeType === NODE_TYPES.COMMENT &&
child.nodeValue.trim() === identification
......@@ -37,7 +35,7 @@ function findComment(node, identification) {
}
}
export default function changePositionByComment(identification, presentParentNode, originalParentNode) {
export default function changePositionByComment(identification: string, presentParentNode: Node, originalParentNode: Node) {
if (!presentParentNode || !originalParentNode) {
return;
}
......@@ -46,11 +44,11 @@ export default function changePositionByComment(identification, presentParentNod
if (!elementNodes.length || !commentNode) {
return;
}
elementNodes.push(elementNodes[elementNodes.length - 1].nextSibling);
elementNodes.unshift(elementNodes[0].previousSibling);
elementNodes.push(elementNodes[elementNodes.length - 1].nextSibling as Node);
elementNodes.unshift(elementNodes[0].previousSibling as Node);
// Deleting comment elements when using commet components will result in component uninstallation errors
for (let i = elementNodes.length - 1; i >= 0; i--) {
presentParentNode.insertBefore(elementNodes[i], commentNode);
}
originalParentNode.appendChild(commentNode);
}
\ No newline at end of file
}
type EventNames = string | string[];
type Listener = (...args: any) => void;
export default function createEventEmitter() {
let events = Object.create(null);
function on(eventNames, listener, direction = false) {
function on(eventNames: EventNames, listener: Listener, direction = false) {
eventNames = getEventNames(eventNames);
let current = events;
const maxIndex = eventNames.length - 1;
......@@ -9,7 +13,7 @@ export default function createEventEmitter() {
const key = eventNames[i];
if (!current[key]) {
current[key] = i === maxIndex ? [] : {};
};
}
current = current[key];
}
if (!Array.isArray(current)) {
......@@ -22,41 +26,43 @@ export default function createEventEmitter() {
}
}
function off(eventNames, listener) {
function off(eventNames: EventNames, listener: Listener) {
const listeners = getListeners(eventNames);
if (!listeners) {
return;
}
const matchIndex = listeners.findIndex(v => v === listener);
const matchIndex = listeners.findIndex((v: Listener) => v === listener);
if (matchIndex !== -1) {
listeners.splice(matchIndex, 1);
}
}
function removeAllListeners(eventNames) {
function removeAllListeners(eventNames: EventNames) {
const listeners = getListeners(eventNames);
if (!listeners) {
return;
}
eventNames = getEventNames(eventNames);
const lastEventName = eventNames.pop();
const event = eventNames.reduce((obj, key) => obj[key], events);
event[lastEventName] = [];
if (lastEventName) {
const event = eventNames.reduce((obj, key) => obj[key], events);
event[lastEventName] = [];
}
}
function emit(eventNames, ...args) {
function emit(eventNames: EventNames, ...args: any) {
const listeners = getListeners(eventNames);
if (!listeners) {
return;
}
for (let i = 0; i < listeners.length; i++) {
if (listeners[i]) {
listeners[i](...args);
for (const listener of listeners) {
if (listener) {
listener(...args);
}
}
}
function listenerCount(eventNames) {
function listenerCount(eventNames: EventNames) {
const listeners = getListeners(eventNames);
return listeners ? listeners.length : 0;
}
......@@ -65,14 +71,16 @@ export default function createEventEmitter() {
events = Object.create(null);
}
function getListeners(eventNames) {
function getListeners(eventNames: EventNames): Listener[] | undefined {
eventNames = getEventNames(eventNames);
try {
return eventNames.reduce((obj, key) => obj[key], events);
} catch (e) {}
} catch (e) {
return;
}
}
function getEventNames(eventNames) {
function getEventNames(eventNames: EventNames): string[] {
if (!eventNames) {
throw new Error('Must exist event name.');
}
......@@ -90,4 +98,4 @@ export default function createEventEmitter() {
listenerCount,
removeAllListeners,
};
};
\ No newline at end of file
}
import {prefix} from './createUniqueIdentification';
export default function createStoreElement() {
export default function createStoreElement(): HTMLElement {
const keepAliveDOM = document.createElement('div');
keepAliveDOM.dataset.type = prefix;
keepAliveDOM.style.display = 'none';
document.body.appendChild(keepAliveDOM);
return keepAliveDOM;
}
\ No newline at end of file
}
......@@ -10,8 +10,8 @@ export const prefix = 'keep-alive';
*/
export default function createUniqueIdentification(length = 6) {
const strings = [];
for (var i = 0; i < length; i++) {
for (let i = 0; i < length; i++) {
strings[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
return `${prefix}-${strings.join('')}`;
}
\ No newline at end of file
}
export default function findDOMNodeByFiberNode(fiberNode) {
export default function findDOMNodeByFiberNode(fiberNode: any): HTMLElement | null {
if (!fiberNode) {
return null;
}
const {
stateNode,
stateNode,
return: parent,
} = fiberNode;
if (!parent) {
......@@ -13,4 +13,4 @@ export default function findDOMNodeByFiberNode(fiberNode) {
return stateNode;
}
return findDOMNodeByFiberNode(parent);
}
\ No newline at end of file
}
import React from 'react';
import {keepAliveProviderTypeName} from '../components/Provider';
import {keepAliveDisplayName} from './keepAlive';
export default function getContextIdentificationByFiberNode(fiberNode) {
let globalKey = null;
export default function getContextIdentificationByFiberNode(fiberNode: any) {
let globalKey: React.Key | null = null;
let typeNames = '';
function getPathsByFiberNode(fiberNode) {
function getPathsByFiberNode(fiberNode: any) {
if (!fiberNode) {
return '';
}
......@@ -12,12 +14,12 @@ export default function getContextIdentificationByFiberNode(fiberNode) {
key,
index,
} = fiberNode;
let typeName = type && type.name ? type.name : '';
const typeName = type && type.displayName;
if (typeName === keepAliveProviderTypeName) {
return '';
}
const joinName = getPathsByFiberNode(fiberNode.return);
if (type && type.displayName && type.displayName.indexOf('keepAlive') !== -1) {
const joinName: string = getPathsByFiberNode(fiberNode.return);
if (type && type.displayName && type.displayName.indexOf(keepAliveDisplayName) !== -1) {
if (!globalKey) {
globalKey = key;
}
......@@ -31,4 +33,4 @@ export default function getContextIdentificationByFiberNode(fiberNode) {
globalKey,
typeNames,
};
}
\ No newline at end of file
}
export default function getDisplayName(Component) {
import React from 'react';
export default function getDisplayName(Component: React.ComponentType) {
return Component.displayName || Component.name || null;
}
\ No newline at end of file
}
export default function getKeepAlive(keepAlive) {
return keepAlive === undefined ? true : keepAlive;
}
\ No newline at end of file
import isRegExp from './isRegExp';
type Pattern = string | string[] | RegExp;
function matches (pattern: Pattern, name: string) {
if (Array.isArray(pattern)) {
return pattern.indexOf(name) > -1;
} else if (typeof pattern === 'string') {
return pattern.split(',').indexOf(name) > -1;
} else if (isRegExp(pattern)) {
return pattern.test(name);
}
return false;
}
export default function getKeepAlive(
name: string,
include?: Pattern,
exclude?: Pattern,
keepAlive?: boolean
) {
if (keepAlive !== undefined) {
return keepAlive;
}
if (
(include && (!name || !matches(include, name))) ||
(exclude && name && matches(exclude, name))
) {
return false;
}
return true;
}
export default function isRegExp(value: RegExp) {
return value && Object.prototype.toString.call(value) === '[object RegExp]';
}
This diff is collapsed.
import md5 from 'js-md5';
import {prefix} from './createUniqueIdentification';
export default function createMD5(string = '', length = 6) {
return `${prefix}-${md5(string).substr(0, length)}`;
}
\ No newline at end of file
export default function createMD5(value: string = '', length = 6) {
return `${prefix}-${md5(value).substr(0, length)}`;
}
export default function noop() {};
\ No newline at end of file
const noop = () => undefined;
export default noop;
/**
* From react
*/
function is(x, y) {
function is(x: any, y: any) {
return (
(x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare
);
......@@ -9,7 +9,7 @@ function is(x, y) {
const hasOwnProperty = Object.prototype.hasOwnProperty;
function shallowEqual(objA, objB) {
function shallowEqual(objA: object, objB: object) {
if (is(objA, objB)) {
return true;
}
......@@ -31,10 +31,10 @@ function shallowEqual(objA, objB) {
}
// Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
for (const key of keysA) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
!hasOwnProperty.call(objB, key) ||
!is(objA[key], objB[key])
) {
return false;
}
......@@ -43,4 +43,4 @@ function shallowEqual(objA, objB) {
return true;
}
export default shallowEqual;
\ No newline at end of file
export default shallowEqual;
......@@ -2,13 +2,26 @@ import React from 'react';
import IdentificationContext from '../contexts/IdentificationContext';
import getDisplayName from './getDisplayName';
export default function withIdentificationContextConsumer(Component) {
const NewComponent = props => (
export interface IIdentificationContextProps {
identification: string;
eventEmitter: any;
keepAlive: boolean;
activated: boolean;
getLifecycle: () => number;
isExisted: () => boolean;
}
export interface IIdentificationContextComponentProps {
_identificationContextProps: IIdentificationContextProps;
}
export default function withIdentificationContextConsumer<P = any>(Component: React.ComponentType<IIdentificationContextComponentProps & P>) {
const NewComponent = (props: P) => (
<IdentificationContext.Consumer>
{contextProps => <Component _identificationContextProps={contextProps || {}} {...props} />}
{(contextProps: IIdentificationContextProps) => <Component _identificationContextProps={contextProps || {}} {...props} />}
</IdentificationContext.Consumer>
);
NewComponent.displayName = `withIdentificationContextConsumer(${getDisplayName(Component)})`;
return NewComponent;
}
\ No newline at end of file
}
import React from 'react';
import {IKeepAliveProviderImpl, IKeepAliveProviderProps} from '../components/Provider';
import KeepAliveContext from '../contexts/KeepAliveContext';
import getDisplayName from './getDisplayName';
export default function withKeepAliveContextConsumer(Component) {
const NewComponent = (props, ref) => (
type IKeepAliveContextProps = IKeepAliveProviderImpl & IKeepAliveProviderProps;
export interface IKeepAliveContextComponentProps {
_keepAliveContextProps: IKeepAliveContextProps;
}
export default function withKeepAliveContextConsumer<P = any>(Component: React.ComponentType<IKeepAliveContextComponentProps & P>) {
const NewComponent = (props: P) => (
<KeepAliveContext.Consumer>
{contextProps => <Component _keepAliveContextProps={contextProps || {}} {...props} ref={ref} />}
{(contextProps: IKeepAliveContextProps) => <Component _keepAliveContextProps={contextProps || {}} {...props} />}
</KeepAliveContext.Consumer>
);
NewComponent.displayName = `withKeepAliveContextConsumer(${getDisplayName(Component)})`;
return React.forwardRef(NewComponent);
}
\ No newline at end of file
return NewComponent;
}
......@@ -6,7 +6,7 @@
"esModuleInterop": true,
"target": "es5",
"lib": ["es6", "dom"],
"allowJs": true,
"declaration": true,
"sourceMap": false,
"jsx": "react",
"moduleResolution": "node",
......
......@@ -13,6 +13,8 @@
"max-classes-per-file": false,
"no-unsafe-finally": false,
"object-literal-sort-keys": false,
"space-before-function-paren": false,
"no-shadowed-variable": false,
"arrow-parens": [true, "ban-single-arg-parens"]
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment