Releases: acdlite/recompose
v0.10.0
Fix production build
Fixes a bug introduced by 0.9.1 that only occurred in production, and so wasn't caught by the tests
Helpful developer warnings
If you use Recompose's compose
function, it will print a warning if a higher-order component helper has insufficient parameters. For example, if you forget to pass an initial state to withReducer
:
compose(
withReducer('state', 'dispatch', reducer), // Forgot initialState
...otherHelpers
)(BaseComponent)
Attempted to compose
withReducer()
with other higher-order component helpers, but it has been applied with 1 too few parameters. Check the implementation of .
These warnings are only printed in development. In production, compose
is an alias for lodash's compose
.
v0.9.0
New util:
componentFromProp()
componentFromProp(propName: string): ReactElementType
Creates a component that accepts a component as a prop and renders it with the remaining props.
Example:
const Button = defaultProps(
{ component: 'button' },
componentFromProp('component')
);
<Button foo="bar" /> // renders <button foo="bar" />
<Button component="a" foo="bar" /> // renders <a foo="bar" />
<Button component={Link} foo="bar" /> // renders <Link foo="bar" />
onlyUpdateForPropTypes()
Like onlyUpdateForKeys()
where the keys are inferred from the propTypes
of the base component.
Thanks, @grabbou!
toClass()
New helper that converts a function component to a class component. Might be useful if you need a ref.
Also added a helper isClassComponent()
that returns whether a component is a React component class.
Thanks @haradakunihiko @py-in-the-sky and @istarkov for your help!
v0.6.0
Static helpers
New helper called setStatic()
adds a static property to the base component. Also added setDisplayName()
and setPropTypes()
helpers. These static helpers are curried and component-last, so they can be composed with higher-order component helpers; however, unlike higher-order component helpers, they mutate the base component instead of returning a new one.
Renamed mapPropsOnUpdate()
-> mapPropsOnChange()
The old name incorrectly implied that the helper used shouldComponentUpdate()
.
v0.5.1
v0.5.0
Housekeeping
Compute initial state from initial props
If the initialState
parameter of withState()
is a function, it is used to compute the initial state given the initial props. For example, to create a counter that starts at a certain value:
const Counter = compose(
withState('count', 'setCounter', props => props.initialCount || 0),
mapProps({ setCounter, ...rest } => ({
increment: () => setCounter(n => n + 1),
decrement: () => setCounter(n => n - 1),
...rest
}))
)(({ count, increment, decrement }) => (
<p>
Count: {count}
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</p>
));
ReactDOM.render(<Counter initialCounter={7} />);
I'm trying to generally avoid function overloading but in some cases (like this one) it makes sense.
Internal optimization: Avoid unnecessary intermediate React elements
Higher-order components are useful and provide a nice programming model, but they aren't free: there is a performance overhead when introducing a new component to the tree. I suspect this cost is negligible compared to the gains achieved by blocking subtrees from re-rendering using shouldComponentUpdate
— which Recompose makes easy with its shouldUpdate()
and onlyUpdateForKeys()
helpers. I'll try to put together some benchmarks so we know what we're dealing with.
However, many of Recompose's higher-order component helpers are implemented using stateless function components rather than class components. Eventually, React will include optimizations for stateless components. Until then, we can do our own optimizations by taking advantage of referential transparency. In other words, creating an element from a stateless function is effectively* the same as calling the function and returning its output.
To accomplish this, Recompose uses a special version of createElement()
that returns the output of stateless functions instead of creating a new element. For class components, it uses the built-in React.createElement()
.
* Stateless function components are not referentially transparent if they access context; we detect that by checking for the existence of contextTypes
.