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 5879916 commit 3b3bd8f
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": "^2.0.4",
"jest-in-case": "^1.0.2",
"kcd-scripts": "^0.44.0",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"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 @@ -90,3 +90,33 @@ it('supports fragments', () => {
cleanup()
expect(document.body.innerHTML).toBe('')
})

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 @@ -3,7 +3,10 @@ import {getQueriesForElement, prettyDOM, fireEvent} from 'dom-testing-library'

const mountedContainers = new Set()

function render(ui, {container, baseElement = container, queries} = {}) {
function render(
element,
{container, baseElement = container, queries, 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 @@ -15,8 +18,14 @@ function render(ui, {container, baseElement = container, queries} = {}) {
// 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 3b3bd8f

Please sign in to comment.