Skip to content

Commit 327c53a

Browse files
committed
Add a warning about undefined children
Warn when `undefined` is returned from a <Route children> function
1 parent afebe67 commit 327c53a

File tree

2 files changed

+86
-46
lines changed

2 files changed

+86
-46
lines changed

packages/react-router/modules/Route.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,29 @@ class Route extends React.Component {
8686
children = null;
8787
}
8888

89+
if (typeof children === "function") {
90+
children = children(props);
91+
92+
if (children === undefined) {
93+
if (__DEV__) {
94+
const { path } = this.props;
95+
96+
warning(
97+
false,
98+
"You returned `undefined` from the `children` function of " +
99+
`<Route${path ? ` path="${path}"` : ""}>, but you ` +
100+
"should have returned a React element or `null`"
101+
);
102+
}
103+
104+
children = null;
105+
}
106+
}
107+
89108
return (
90109
<RouterContext.Provider value={props}>
91-
{children
92-
? typeof children === "function"
93-
? children(props)
94-
: isEmptyChildren(children)
95-
? null
96-
: children
110+
{children && !isEmptyChildren(children)
111+
? children
97112
: props.match
98113
? component
99114
? React.createElement(component, props)

packages/react-router/modules/__tests__/Route-test.js

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -213,55 +213,80 @@ describe("A <Route>", () => {
213213
});
214214

215215
describe("the `children` prop", () => {
216-
it("renders a child element", () => {
217-
const text = "bubblegum";
216+
describe("that is an element", () => {
217+
it("renders", () => {
218+
const text = "bubblegum";
218219

219-
ReactDOM.render(
220-
<MemoryRouter initialEntries={["/"]}>
221-
<Route path="/">
222-
<h1>{text}</h1>
223-
</Route>
224-
</MemoryRouter>,
225-
node
226-
);
220+
ReactDOM.render(
221+
<MemoryRouter initialEntries={["/"]}>
222+
<Route path="/">
223+
<h1>{text}</h1>
224+
</Route>
225+
</MemoryRouter>,
226+
node
227+
);
227228

228-
expect(node.innerHTML).toContain(text);
229+
expect(node.innerHTML).toContain(text);
230+
});
229231
});
230232

231-
it("renders a function", () => {
232-
const text = "bubblegum";
233+
describe("that is a function", () => {
234+
it("receives { history, location, match } props", () => {
235+
const history = createHistory();
233236

234-
ReactDOM.render(
235-
<MemoryRouter initialEntries={["/"]}>
236-
<Route path="/" children={() => <h1>{text}</h1>} />
237-
</MemoryRouter>,
238-
node
239-
);
237+
let props = null;
238+
ReactDOM.render(
239+
<Router history={history}>
240+
<Route
241+
path="/"
242+
children={p => {
243+
props = p;
244+
return null;
245+
}}
246+
/>
247+
</Router>,
248+
node
249+
);
240250

241-
expect(node.innerHTML).toContain(text);
242-
});
251+
expect(props).not.toBe(null);
252+
expect(props.history).toBe(history);
253+
expect(typeof props.location).toBe("object");
254+
expect(typeof props.match).toBe("object");
255+
});
243256

244-
it("receives { history, location, match } props", () => {
245-
const history = createHistory();
257+
it("renders", () => {
258+
const text = "bubblegum";
246259

247-
let props = null;
248-
ReactDOM.render(
249-
<Router history={history}>
250-
<Route
251-
path="/"
252-
children={p => {
253-
props = p;
254-
return null;
255-
}}
256-
/>
257-
</Router>,
258-
node
259-
);
260+
ReactDOM.render(
261+
<MemoryRouter initialEntries={["/"]}>
262+
<Route path="/" children={() => <h1>{text}</h1>} />
263+
</MemoryRouter>,
264+
node
265+
);
260266

261-
expect(props).not.toBe(null);
262-
expect(props.history).toBe(history);
263-
expect(typeof props.location).toBe("object");
264-
expect(typeof props.match).toBe("object");
267+
expect(node.innerHTML).toContain(text);
268+
});
269+
270+
describe("that returns `undefined`", () => {
271+
it("logs a warning to the console and renders nothing", () => {
272+
spyOn(console, "error");
273+
274+
ReactDOM.render(
275+
<MemoryRouter initialEntries={["/"]}>
276+
<Route path="/" children={() => undefined} />
277+
</MemoryRouter>,
278+
node
279+
);
280+
281+
expect(node.innerHTML).toEqual("");
282+
283+
expect(console.error).toHaveBeenCalledWith(
284+
expect.stringContaining(
285+
"You returned `undefined` from the `children` function"
286+
)
287+
);
288+
});
289+
});
265290
});
266291

267292
describe("that is an empty array (as in Preact)", () => {

0 commit comments

Comments
 (0)