Skip to content

Commit ee2f07a

Browse files
jeetissrenatorib
authored andcommitted
Fix composed components order after rerender (#124)
* fix rerenders * add test * use better api
1 parent 9665438 commit ee2f07a

File tree

5 files changed

+64
-22
lines changed

5 files changed

+64
-22
lines changed

.size-snapshot.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
{
22
"dist/react-powerplug.umd.js": {
3-
"bundled": 23707,
4-
"minified": 9407,
5-
"gzipped": 2594
3+
"bundled": 23752,
4+
"minified": 9415,
5+
"gzipped": 2597
66
},
77
"dist/react-powerplug.cjs.js": {
8-
"bundled": 20771,
9-
"minified": 10819,
10-
"gzipped": 2483
8+
"bundled": 20814,
9+
"minified": 10827,
10+
"gzipped": 2486
1111
},
1212
"dist/react-powerplug.esm.js": {
13-
"bundled": 20109,
14-
"minified": 10259,
15-
"gzipped": 2344,
13+
"bundled": 20152,
14+
"minified": 10267,
15+
"gzipped": 2349,
1616
"treeshaked": {
1717
"rollup": {
1818
"code": 365,

src/utils/compose.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import renderProps from './renderProps'
44
const isElement = element => typeof element.type === 'function'
55

66
const compose = (...elements) => {
7+
const reversedElements = elements.reverse()
8+
79
return composedProps => {
810
// Stack children arguments recursively and pass
911
// it down until the last component that render children
@@ -29,7 +31,7 @@ const compose = (...elements) => {
2931
return elementFn(element, {}, renderFn)
3032
}
3133

32-
return stackProps(elements.length - 1, elements.reverse())
34+
return stackProps(elements.length - 1, reversedElements)
3335
}
3436
}
3537

tests/components/Compose.test.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
import * as React from 'react'
22
import TestRenderer from 'react-test-renderer'
33
import { Compose, Counter, Toggle } from '../../src'
4+
import { lastCallArgs } from './utils'
45

56
test('<Compose />', () => {
6-
let lastCallProps = null
7-
const renderFn = (...props) => {
8-
lastCallProps = props
9-
return null
10-
}
7+
const renderFn = jest.fn().mockReturnValue(null)
118

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

16-
expect(lastCallProps[0].count).toBe(0)
17-
expect(lastCallProps[1].on).toBe(false)
13+
expect(renderFn).toBeCalledTimes(1)
14+
expect(renderFn).lastCalledWith(
15+
expect.objectContaining({ count: 0 }),
16+
expect.objectContaining({ on: false })
17+
)
1818

19-
lastCallProps[0].inc()
20-
lastCallProps[0].incBy(3)
21-
lastCallProps[1].toggle()
19+
lastCallArgs(renderFn)[0].inc()
20+
lastCallArgs(renderFn)[0].incBy(3)
21+
lastCallArgs(renderFn)[1].toggle()
2222

23-
expect(lastCallProps[0].count).toBe(4)
24-
expect(lastCallProps[1].on).toBe(true)
23+
expect(renderFn).toBeCalledTimes(4)
24+
expect(renderFn).lastCalledWith(
25+
expect.objectContaining({ count: 4 }),
26+
expect.objectContaining({ on: true })
27+
)
2528
})

tests/components/utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
const last = arr => arr[Math.max(0, arr.length - 1)]
22

33
export const lastCallArg = mockFn => last(mockFn.mock.calls)[0]
4+
export const lastCallArgs = mockFn => last(mockFn.mock.calls)

tests/utils/compose.test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from 'react'
2+
import TestRenderer from 'react-test-renderer'
3+
import { compose, Counter, Toggle } from '../../src'
4+
5+
test('rerender composed component', () => {
6+
const CounterToggle = compose(Counter, Toggle)
7+
const renderFn = jest.fn().mockReturnValue(null)
8+
let rerender = null
9+
10+
TestRenderer.create(
11+
<Toggle>
12+
{({ on, toggle }) => {
13+
rerender = toggle
14+
15+
return (
16+
// hard rerender
17+
<CounterToggle key={on} render={renderFn} />
18+
)
19+
}}
20+
</Toggle>
21+
)
22+
23+
expect(renderFn).toBeCalledTimes(1)
24+
expect(renderFn).lastCalledWith(
25+
expect.objectContaining({ count: 0 }),
26+
expect.objectContaining({ on: false })
27+
)
28+
29+
rerender()
30+
31+
expect(renderFn).toBeCalledTimes(2)
32+
expect(renderFn).lastCalledWith(
33+
expect.objectContaining({ count: 0 }),
34+
expect.objectContaining({ on: false })
35+
)
36+
})

0 commit comments

Comments
 (0)