Skip to content

Commit 4efeb21

Browse files
committed
Added an example of nested HOC with connect. Fixed #5
1 parent 2d234ef commit 4efeb21

File tree

4 files changed

+84
-8
lines changed

4 files changed

+84
-8
lines changed

playground/src/hoc/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * from './with-connected-count';
12
export * from './with-error-boundary';
23
export * from './with-state';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { RootState } from 'MyTypes';
2+
import React from 'react';
3+
import { connect } from 'react-redux';
4+
import { Diff } from 'utility-types';
5+
import { countersActions, countersSelectors } from '../features/counters';
6+
7+
// These props will be injected into the base component
8+
interface InjectedProps {
9+
count: number;
10+
onIncrement: () => void;
11+
}
12+
13+
export const withConnectedCount = <BaseProps extends InjectedProps>(
14+
BaseComponent: React.ComponentType<BaseProps>
15+
) => {
16+
type HocProps = Diff<BaseProps, InjectedProps> & {
17+
// here you can extend hoc with new props
18+
initialCount?: number;
19+
};
20+
21+
const mapStateToProps = (state: RootState) => ({
22+
count: countersSelectors.getReduxCounter(state.counters),
23+
});
24+
25+
const dispatchProps = {
26+
onIncrement: countersActions.increment,
27+
};
28+
29+
class Hoc extends React.Component<InjectedProps> {
30+
// Enhance component name for debugging and React-Dev-Tools
31+
static displayName = `withConnectedCount(${BaseComponent.name})`;
32+
// reference to original wrapped component
33+
static readonly WrappedComponent = BaseComponent;
34+
35+
render() {
36+
const { count, onIncrement, ...restProps } = this.props;
37+
38+
return (
39+
<BaseComponent
40+
count={count} // injected
41+
onIncrement={onIncrement} // injected
42+
{...(restProps as BaseProps)}
43+
/>
44+
);
45+
}
46+
}
47+
48+
const ConnectedHoc = connect<
49+
ReturnType<typeof mapStateToProps>,
50+
typeof dispatchProps,
51+
HocProps,
52+
RootState
53+
>(
54+
mapStateToProps,
55+
dispatchProps
56+
)(Hoc);
57+
58+
return ConnectedHoc;
59+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as React from 'react';
2+
3+
import { withConnectedCount } from '../hoc';
4+
import { FCCounter } from '../components';
5+
6+
const FCCounterWithConnectedCount = withConnectedCount(FCCounter);
7+
8+
export default () => (
9+
<FCCounterWithConnectedCount initialCount={5} label={'FCCounterWithState'} />
10+
);

playground/src/routes/Home.tsx

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
import * as React from 'react';
22

3-
import FCCounter from '../components/fc-counter.usage';
4-
import FCSpreadAttributes from '../components/fc-spread-attributes.usage';
5-
import ClassCounter from '../components/class-counter.usage';
6-
import ClassCounterWithDefaultProps from '../components/class-counter-with-default-props.usage';
3+
import FCCounterUsage from '../components/fc-counter.usage';
4+
import FCSpreadAttributesUsage from '../components/fc-spread-attributes.usage';
5+
import ClassCounterUsage from '../components/class-counter.usage';
6+
import ClassCounterWithDefaultPropsUsage from '../components/class-counter-with-default-props.usage';
77
import UserListUsage from '../components/generic-list.usage';
8+
import WithErrorBoundaryUsage from '../hoc/with-error-boundary.usage';
9+
import WithStateUsage from '../hoc/with-state.usage';
10+
import WithConnectedCountUsage from '../hoc/with-connected-count.usage';
811

912
export default () => {
1013
return (
1114
<section>
12-
<FCCounter />
13-
<FCSpreadAttributes />
14-
<ClassCounter />
15-
<ClassCounterWithDefaultProps />
15+
<FCCounterUsage />
16+
<FCSpreadAttributesUsage />
17+
<ClassCounterUsage />
18+
<ClassCounterWithDefaultPropsUsage />
1619
<UserListUsage />
20+
<WithErrorBoundaryUsage />
21+
<WithStateUsage />
22+
<WithConnectedCountUsage />
1723
</section>
1824
);
1925
};

0 commit comments

Comments
 (0)