69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import React, { useContext, useMemo } from 'react';
|
|
import { AppContext } from './AppContext';
|
|
import { DispatchObject } from '../util/types';
|
|
import { AppState } from './state';
|
|
|
|
interface ConnectParams<TOwnProps, TStateProps, TDispatchProps> {
|
|
mapStateToProps?: (state: AppState, props: TOwnProps) => TStateProps;
|
|
mapDispatchToProps?: TDispatchProps;
|
|
component: React.ComponentType<any>;
|
|
}
|
|
|
|
export function connect<
|
|
TOwnProps = any,
|
|
TStateProps = any,
|
|
TDispatchProps = any
|
|
>({
|
|
mapStateToProps = () => ({} as TStateProps),
|
|
mapDispatchToProps = {} as TDispatchProps,
|
|
component,
|
|
}: ConnectParams<
|
|
TOwnProps,
|
|
TStateProps,
|
|
TDispatchProps
|
|
>): React.FunctionComponent<TOwnProps> {
|
|
const Connect = (ownProps: TOwnProps) => {
|
|
const context = useContext(AppContext);
|
|
|
|
const dispatchFuncs = useMemo(() => {
|
|
const dispatchFuncs: { [key: string]: any } = {};
|
|
if (mapDispatchToProps) {
|
|
Object.keys(mapDispatchToProps).forEach((key) => {
|
|
const oldFunc = (mapDispatchToProps as any)[key];
|
|
const newFunc = (...args: any) => {
|
|
const dispatchFunc = oldFunc(...args);
|
|
if (typeof dispatchFunc === 'object') {
|
|
context.dispatch(dispatchFunc);
|
|
} else {
|
|
const result = dispatchFunc(context.dispatch);
|
|
if (typeof result === 'object' && result.then) {
|
|
result.then((dispatchObject?: DispatchObject) => {
|
|
if (dispatchObject && dispatchObject.type) {
|
|
context.dispatch(dispatchObject);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|
|
dispatchFuncs[key] = newFunc;
|
|
});
|
|
}
|
|
return dispatchFuncs;
|
|
// eslint-disable-next-line
|
|
}, [mapDispatchToProps]);
|
|
|
|
const props = useMemo(() => {
|
|
return Object.assign(
|
|
{},
|
|
ownProps,
|
|
mapStateToProps(context.state, ownProps),
|
|
dispatchFuncs
|
|
);
|
|
// eslint-disable-next-line
|
|
}, [ownProps, context.state]);
|
|
|
|
return React.createElement(component, props);
|
|
};
|
|
return React.memo(Connect as any);
|
|
}
|