Skip to content

Commit

Permalink
fix(hooks): flush useEffect hooks with a rerender
Browse files Browse the repository at this point in the history
  • Loading branch information
alexkrolick committed Nov 5, 2018
1 parent ce1d1f1 commit 3591cb0
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"jest-dom": "^1.3.1",
"jest-in-case": "^1.0.2",
"kcd-scripts": "^0.39.1",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react": "^16.7.0-alpha.0",
"react-dom": "^16.7.0-alpha.0",
"react-redux": "^5.0.7",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
Expand Down
32 changes: 31 additions & 1 deletion src/__tests__/render.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'jest-dom/extend-expect'
import React from 'react'
import React, {useEffect} from 'react'
import ReactDOM from 'react-dom'
import {render, cleanup} from '../'

Expand Down Expand Up @@ -73,3 +73,33 @@ it('cleansup document', () => {
expect(document.body.innerHTML).toBe('')
expect(spy).toHaveBeenCalledTimes(1)
})

test('flushes hooks by default', () => {
let count = 0
const effectFn = jest.fn(() => {
count++
})
function SideEffectfulComponent() {
useEffect(effectFn)
return <div />
}
expect(count).toBe(0)
render(<SideEffectfulComponent />)
expect(effectFn).toHaveBeenCalled()
expect(count).toBe(1)
})

test('does not flush hooks if flushEffects option is false', () => {
let count = 0
const effectFn = jest.fn(() => {
count++
})
function SideEffectfulComponent() {
useEffect(effectFn)
return <div />
}
expect(count).toBe(0)
render(<SideEffectfulComponent />, {flushEffects: false})
expect(effectFn).not.toHaveBeenCalled()
expect(count).toBe(0)
})
13 changes: 11 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {getQueriesForElement, prettyDOM} from 'dom-testing-library'

const mountedContainers = new Set()

function render(ui, {container, baseElement = container} = {}) {
function render(
element,
{container, baseElement = container, flushEffects = true} = {},
) {
if (!container) {
// default to document.body instead of documentElement to avoid output of potentially-large
// head elements (such as JSS style blocks) in debug output
Expand All @@ -16,8 +19,14 @@ function render(ui, {container, baseElement = container} = {}) {
// added to document.body so the cleanup method works regardless of whether
// they're passing us a custom container or not.
mountedContainers.add(container)
ReactDOM.render(element, container)

// useEffect hooks are always called before the next render;
// render again to trigger the effects
if (flushEffects) {
ReactDOM.render(element, container)
}

ReactDOM.render(ui, container)
return {
container,
baseElement,
Expand Down

0 comments on commit 3591cb0

Please sign in to comment.