diff --git a/package.json b/package.json
index 67bde194..54f531f1 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,8 @@
},
"devDependencies": {
"@reach/router": "^1.2.1",
- "@types/react-dom": "^16.0.9",
+ "@types/react": "^16.8.3",
+ "@types/react-dom": "^16.8.2",
"axios": "^0.18.0",
"eslint-import-resolver-jest": "^2.1.1",
"history": "^4.7.2",
diff --git a/src/__tests__/render.js b/src/__tests__/render.js
index 5ee0dc6f..0ffe1322 100644
--- a/src/__tests__/render.js
+++ b/src/__tests__/render.js
@@ -90,3 +90,24 @@ it('supports fragments', () => {
cleanup()
expect(document.body.innerHTML).toBe('')
})
+
+test('renders options.wrapper around node', () => {
+ const WrapperComponent = ({children}) => (
+
{children}
+ )
+
+ const {container, getByTestId} = render(, {
+ wrapper: WrapperComponent,
+ })
+
+ expect(getByTestId('wrapper')).toBeInTheDocument()
+ expect(container.firstChild).toMatchInlineSnapshot(`
+
+`)
+})
diff --git a/src/index.js b/src/index.js
index 89a31e2c..70bf83c2 100644
--- a/src/index.js
+++ b/src/index.js
@@ -11,7 +11,13 @@ const mountedContainers = new Set()
function render(
ui,
- {container, baseElement = container, queries, hydrate = false} = {},
+ {
+ container,
+ baseElement = container,
+ queries,
+ hydrate = false,
+ wrapper: WrapperComponent,
+ } = {},
) {
if (!container) {
// default to document.body instead of documentElement to avoid output of potentially-large
@@ -25,13 +31,20 @@ function render(
// they're passing us a custom container or not.
mountedContainers.add(container)
+
+ const wrapUiIfNeeded = innerElement =>
+ WrapperComponent
+ ? React.createElement(WrapperComponent, null, innerElement)
+ : innerElement
+
act(() => {
if (hydrate) {
- ReactDOM.hydrate(ui, container)
+ ReactDOM.hydrate(wrapUiIfNeeded(ui), container)
} else {
- ReactDOM.render(ui, container)
+ ReactDOM.render(wrapUiIfNeeded(ui), container)
}
})
+
return {
container,
baseElement,
@@ -39,7 +52,7 @@ function render(
debug: (el = baseElement) => console.log(prettyDOM(el)),
unmount: () => ReactDOM.unmountComponentAtNode(container),
rerender: rerenderUi => {
- render(rerenderUi, {container, baseElement})
+ render(wrapUiIfNeeded(rerenderUi), {container, baseElement})
// Intentionally do not return anything to avoid unnecessarily complicating the API.
// folks can use all the same utilities we return in the first place that are bound to the container
},
@@ -68,25 +81,20 @@ function testHook(callback, options = {}) {
const result = {
current: null,
}
- const toRender = () => {
- const hookRender = (
-
- {res => {
- result.current = res
- }}
-
- )
- if (options.wrapper) {
- return React.createElement(options.wrapper, null, hookRender)
- }
- return hookRender
- }
- const {unmount, rerender: rerenderComponent} = render(toRender())
+ const toRender = () => (
+
+ {res => {
+ result.current = res
+ }}
+
+ )
+
+ const {unmount, rerender: rerenderComponent} = render(toRender(), options)
return {
result,
unmount,
rerender: () => {
- rerenderComponent(toRender())
+ rerenderComponent(toRender(), options)
},
}
}
diff --git a/typings/index.d.ts b/typings/index.d.ts
index 16594936..af09f778 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -25,17 +25,16 @@ export type HookResult = {
unmount: () => boolean
}
-export type HookOptions = {
- wrapper: React.FunctionComponent
-}
-
export interface RenderOptions {
container?: HTMLElement
baseElement?: HTMLElement
hydrate?: boolean
queries?: Q
+ wrapper?: React.ComponentType
}
+export type HookOptions = RenderOptions
+
type Omit = Pick>
/**