Skip to content

Commit

Permalink
Fix composed components order after rerender (#124)
Browse files Browse the repository at this point in the history
* fix rerenders

* add test

* use better api
  • Loading branch information
jeetiss authored and renatorib committed Jun 15, 2018
1 parent 9665438 commit ee2f07a
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 22 deletions.
18 changes: 9 additions & 9 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"dist/react-powerplug.umd.js": {
"bundled": 23707,
"minified": 9407,
"gzipped": 2594
"bundled": 23752,
"minified": 9415,
"gzipped": 2597
},
"dist/react-powerplug.cjs.js": {
"bundled": 20771,
"minified": 10819,
"gzipped": 2483
"bundled": 20814,
"minified": 10827,
"gzipped": 2486
},
"dist/react-powerplug.esm.js": {
"bundled": 20109,
"minified": 10259,
"gzipped": 2344,
"bundled": 20152,
"minified": 10267,
"gzipped": 2349,
"treeshaked": {
"rollup": {
"code": 365,
Expand Down
4 changes: 3 additions & 1 deletion src/utils/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import renderProps from './renderProps'
const isElement = element => typeof element.type === 'function'

const compose = (...elements) => {
const reversedElements = elements.reverse()

return composedProps => {
// Stack children arguments recursively and pass
// it down until the last component that render children
Expand All @@ -29,7 +31,7 @@ const compose = (...elements) => {
return elementFn(element, {}, renderFn)
}

return stackProps(elements.length - 1, elements.reverse())
return stackProps(elements.length - 1, reversedElements)
}
}

Expand Down
27 changes: 15 additions & 12 deletions tests/components/Compose.test.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import * as React from 'react'
import TestRenderer from 'react-test-renderer'
import { Compose, Counter, Toggle } from '../../src'
import { lastCallArgs } from './utils'

test('<Compose />', () => {
let lastCallProps = null
const renderFn = (...props) => {
lastCallProps = props
return null
}
const renderFn = jest.fn().mockReturnValue(null)

TestRenderer.create(
<Compose components={[Counter, Toggle]} render={renderFn} />
)

expect(lastCallProps[0].count).toBe(0)
expect(lastCallProps[1].on).toBe(false)
expect(renderFn).toBeCalledTimes(1)
expect(renderFn).lastCalledWith(
expect.objectContaining({ count: 0 }),
expect.objectContaining({ on: false })
)

lastCallProps[0].inc()
lastCallProps[0].incBy(3)
lastCallProps[1].toggle()
lastCallArgs(renderFn)[0].inc()
lastCallArgs(renderFn)[0].incBy(3)
lastCallArgs(renderFn)[1].toggle()

expect(lastCallProps[0].count).toBe(4)
expect(lastCallProps[1].on).toBe(true)
expect(renderFn).toBeCalledTimes(4)
expect(renderFn).lastCalledWith(
expect.objectContaining({ count: 4 }),
expect.objectContaining({ on: true })
)
})
1 change: 1 addition & 0 deletions tests/components/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const last = arr => arr[Math.max(0, arr.length - 1)]

export const lastCallArg = mockFn => last(mockFn.mock.calls)[0]
export const lastCallArgs = mockFn => last(mockFn.mock.calls)
36 changes: 36 additions & 0 deletions tests/utils/compose.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as React from 'react'
import TestRenderer from 'react-test-renderer'
import { compose, Counter, Toggle } from '../../src'

test('rerender composed component', () => {
const CounterToggle = compose(Counter, Toggle)
const renderFn = jest.fn().mockReturnValue(null)
let rerender = null

TestRenderer.create(
<Toggle>
{({ on, toggle }) => {
rerender = toggle

return (
// hard rerender
<CounterToggle key={on} render={renderFn} />
)
}}
</Toggle>
)

expect(renderFn).toBeCalledTimes(1)
expect(renderFn).lastCalledWith(
expect.objectContaining({ count: 0 }),
expect.objectContaining({ on: false })
)

rerender()

expect(renderFn).toBeCalledTimes(2)
expect(renderFn).lastCalledWith(
expect.objectContaining({ count: 0 }),
expect.objectContaining({ on: false })
)
})

0 comments on commit ee2f07a

Please sign in to comment.