Retainer (React + container) is a small tool to compose render prop components.
yarn add @danwang/retainer
A Consumer<T> is a React component that accepts a single prop children of
type (T) => ReactNode.
A Retainer<T> is a container wrapping a Consumer<T> with methods for
transforming the provided values.
A typical flow looks like:
- Put the component in a
Retainer - Transform the
Retainer - Extract a component or ReactElement from the
Retainer
Using the context API (React 16.3+):
import * as Retainer from "@danwang/retainer";
const Context = React.createContext({
value: 0,
setValue: () => () => {}
});
class App extends React.Component {
state = { value: 0 };
handleSetValue = (value: number) => () => this.setState({ value });
render() {
const context = {
value: this.state.value,
setValue: this.handleSetValue
};
return (
<Context.Provider value={context}>
<Root />
</Context.Provider>
);
}
}
const Root = () =>
Retainer.make(Context.Consumer)
.map(context => (
<div>
Count is {context.value}
<button onClick={context.setValue(context.value + 1)}>+</button>
</div>
))
.toReactElement();
ReactDOM.render(<App />, element);Creates a Retainer containing the component.
Applies a function to the provided value of the interior component.
Applies a function returning a Retainer to the provided value of the interior
component, flattening one level of nested Retainers.
Returns a render prop component that provides the interior value.
If the interior type is a ReactElement, returns a ReactElement which, when
mounted, mounts necessary Consumer components to render the interior value.