Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ I highly recommend to add a bounty to the issue that you're waiting for to incre
- [- HOC wrapping a component](#--hoc-wrapping-a-component)
- [- HOC wrapping a component and injecting props](#--hoc-wrapping-a-component-and-injecting-props)
- [- Nested HOC - wrapping a component, injecting props and connecting to redux 🌟](#--nested-hoc---wrapping-a-component-injecting-props-and-connecting-to-redux-)
- [- Recompose `withStateHandlers` HOC](#--recompose-withstatehandlers-hoc)
- [Redux Connected Components](#redux-connected-components)
- [- Redux connected counter](#--redux-connected-counter)
- [- Redux connected counter with own props](#--redux-connected-counter-with-own-props)
Expand Down Expand Up @@ -974,6 +975,81 @@ export default () => (

[⇧ back to top](#table-of-contents)


### - Recompose `withStateHandlers` HOC

Adds typed local state to a function component with Recompose. The example keeps the wrapped component props separate from the props injected by the enhancer, which is the key TypeScript pattern when composing Recompose HOCs.

```tsx
import React from 'react';
import { withStateHandlers } from 'recompose';
import { Diff } from 'utility-types';

// These props will be injected into the base component by Recompose.
interface InjectedProps {
count: number;
onIncrement: () => void;
}

interface EnhancerProps {
initialCount?: number;
}

type State = Readonly<{
count: number;
}>;

type Updaters = Readonly<{
onIncrement: () => State;
}>;

const createInitialState = ({ initialCount = 0 }: EnhancerProps): State => ({
count: initialCount,
});

const stateUpdaters = {
onIncrement: ({ count }: State) => () => ({ count: count + 1 }),
};

export const withRecomposeStateHandlers = <BaseProps extends InjectedProps>(
BaseComponent: React.ComponentType<BaseProps>
) =>
withStateHandlers<
State,
Updaters,
Diff<BaseProps, InjectedProps> & EnhancerProps
>(
createInitialState,
stateUpdaters
)(
BaseComponent as React.ComponentType<
Diff<BaseProps, InjectedProps> & EnhancerProps & State & Updaters
>
);

```
<details><summary><i>Click to expand</i></summary><p>

```tsx
import * as React from 'react';

import { FCCounter } from '../components';
import { withRecomposeStateHandlers } from '../hoc';

const FCCounterWithRecomposeStateHandlers = withRecomposeStateHandlers(FCCounter);

export default () => (
<FCCounterWithRecomposeStateHandlers
label={'FCCounterWithRecomposeStateHandlers'}
initialCount={3}
/>
);

```
</p></details>

[⇧ back to top](#table-of-contents)

---

## Redux Connected Components
Expand Down
11 changes: 11 additions & 0 deletions README_SOURCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ I highly recommend to add a bounty to the issue that you're waiting for to incre
- [- HOC wrapping a component](#--hoc-wrapping-a-component)
- [- HOC wrapping a component and injecting props](#--hoc-wrapping-a-component-and-injecting-props)
- [- Nested HOC - wrapping a component, injecting props and connecting to redux 🌟](#--nested-hoc---wrapping-a-component-injecting-props-and-connecting-to-redux-)
- [- Recompose `withStateHandlers` HOC](#--recompose-withstatehandlers-hoc)
- [Redux Connected Components](#redux-connected-components)
- [- Redux connected counter](#--redux-connected-counter)
- [- Redux connected counter with own props](#--redux-connected-counter-with-own-props)
Expand Down Expand Up @@ -438,6 +439,16 @@ Adds error handling using componentDidCatch to any component

[⇧ back to top](#table-of-contents)


### - Recompose `withStateHandlers` HOC

Adds typed local state to a function component with Recompose. The example keeps the wrapped component props separate from the props injected by the enhancer, which is the key TypeScript pattern when composing Recompose HOCs.

::codeblock='playground/src/hoc/with-recompose-state-handlers.tsx'::
::expander='playground/src/hoc/with-recompose-state-handlers.usage.tsx'::

[⇧ back to top](#table-of-contents)

---

## Redux Connected Components
Expand Down
Loading