Skip to content
This repository has been archived by the owner on Sep 10, 2022. It is now read-only.

Commit

Permalink
New lifecycles support (#647)
Browse files Browse the repository at this point in the history
* Remove cache from withHandlers

* Update createSink

* Update withPropsOnChange

* remove memoize as useless

* Simplify code
  • Loading branch information
istarkov committed Apr 18, 2018
1 parent f011941 commit 6d3765a
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 68 deletions.
44 changes: 0 additions & 44 deletions src/packages/recompose/__tests__/withHandlers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,50 +60,6 @@ test('withHandlers passes immutable handlers', () => {
)
})

test('withHandlers caches handlers properly', () => {
const handlerCreationSpy = sinon.spy()
const handlerCallSpy = sinon.spy()

const enhance = withHandlers({
handler: props => {
handlerCreationSpy(props)
return val => {
handlerCallSpy(val)
}
},
})

const component = sinon.spy(() => null)
const Div = enhance(component)

const wrapper = mount(<Div foo="bar" />)
const { handler } = component.firstCall.args[0]

// Don't create handler until it is called
expect(handlerCreationSpy.callCount).toBe(0)
expect(handlerCallSpy.callCount).toBe(0)

handler(1)
expect(handlerCreationSpy.callCount).toBe(1)
expect(handlerCreationSpy.args[0]).toEqual([{ foo: 'bar' }])
expect(handlerCallSpy.callCount).toBe(1)
expect(handlerCallSpy.args[0]).toEqual([1])

// Props haven't changed; should use cached handler
handler(2)
expect(handlerCreationSpy.callCount).toBe(1)
expect(handlerCallSpy.callCount).toBe(2)
expect(handlerCallSpy.args[1]).toEqual([2])

wrapper.setProps({ foo: 'baz' })
handler(3)
// Props did change; handler should be recreated
expect(handlerCreationSpy.callCount).toBe(2)
expect(handlerCreationSpy.args[1]).toEqual([{ foo: 'baz' }])
expect(handlerCallSpy.callCount).toBe(3)
expect(handlerCallSpy.args[2]).toEqual([3])
})

test('withHandlers warns if handler is not a higher-order function', () => {
const error = sinon.stub(console, 'error')

Expand Down
2 changes: 1 addition & 1 deletion src/packages/recompose/__tests__/withPropsOnChange-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import * as React from 'react'
import { mount } from 'enzyme'
import sinon from 'sinon'
import { withPropsOnChange, withState, flattenProp, compose } from '../'
Expand Down
14 changes: 9 additions & 5 deletions src/packages/recompose/createSink.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Component } from 'react'
import { polyfill } from 'react-lifecycles-compat'

const createSink = callback =>
const createSink = callback => {
class Sink extends Component {
componentWillMount() {
callback(this.props)
}
state = {}

componentWillReceiveProps(nextProps) {
static getDerivedStateFromProps(nextProps) {
callback(nextProps)
return null
}

render() {
return null
}
}

polyfill(Sink)
return Sink
}

export default createSink
14 changes: 1 addition & 13 deletions src/packages/recompose/withHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,10 @@ import mapValues from './utils/mapValues'
const withHandlers = handlers => BaseComponent => {
const factory = createFactory(BaseComponent)
class WithHandlers extends Component {
cachedHandlers = {}

handlers = mapValues(
typeof handlers === 'function' ? handlers(this.props) : handlers,
(createHandler, handlerName) => (...args) => {
const cachedHandler = this.cachedHandlers[handlerName]
if (cachedHandler) {
return cachedHandler(...args)
}

createHandler => (...args) => {
const handler = createHandler(this.props)
this.cachedHandlers[handlerName] = handler

if (
process.env.NODE_ENV !== 'production' &&
Expand All @@ -35,10 +27,6 @@ const withHandlers = handlers => BaseComponent => {
}
)

componentWillReceiveProps() {
this.cachedHandlers = {}
}

render() {
return factory({
...this.props,
Expand Down
22 changes: 17 additions & 5 deletions src/packages/recompose/withPropsOnChange.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { createFactory, Component } from 'react'
import { polyfill } from 'react-lifecycles-compat'
import pick from './utils/pick'
import shallowEqual from './shallowEqual'
import setDisplayName from './setDisplayName'
Expand All @@ -16,27 +17,38 @@ const withPropsOnChange = (shouldMapOrKeys, propsMapper) => BaseComponent => {
)

class WithPropsOnChange extends Component {
computedProps = propsMapper(this.props)
state = {
computedProps: propsMapper(this.props),
prevProps: this.props,
}

componentWillReceiveProps(nextProps) {
if (shouldMap(this.props, nextProps)) {
this.computedProps = propsMapper(nextProps)
static getDerivedStateFromProps(nextProps, prevState) {
if (shouldMap(prevState.prevProps, nextProps)) {
return {
computedProps: propsMapper(nextProps),
prevProps: nextProps,
}
}

return null
}

render() {
return factory({
...this.props,
...this.computedProps,
...this.state.computedProps,
})
}
}

polyfill(WithPropsOnChange)

if (process.env.NODE_ENV !== 'production') {
return setDisplayName(wrapDisplayName(BaseComponent, 'withPropsOnChange'))(
WithPropsOnChange
)
}

return WithPropsOnChange
}

Expand Down

0 comments on commit 6d3765a

Please sign in to comment.