From 017f692af74f5797c65d86265c063bc0ea829e13 Mon Sep 17 00:00:00 2001 From: StringEpsilon Date: Tue, 2 Apr 2019 15:12:50 +0200 Subject: [PATCH] Fixed maximum update depth exceeded caused by Redirect. (#6674) * Redirect: Failing test for rendering in functional component * Properly check if location matches in Fixes #6673 * Redirect: Handle all eventualities of to strings. * Redirect: Add update depth test with 'to' as location * Redirect: Simplify and rename tests. * Redirect: work around locationsAreEquals quirk. --- packages/react-router/modules/Redirect.js | 11 +++++++- .../modules/__tests__/Redirect-test.js | 27 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/packages/react-router/modules/Redirect.js b/packages/react-router/modules/Redirect.js index f891a7acfc..f05dce407c 100644 --- a/packages/react-router/modules/Redirect.js +++ b/packages/react-router/modules/Redirect.js @@ -43,7 +43,16 @@ function Redirect({ computedMatch, to, push = false }) { method(location); }} onUpdate={(self, prevProps) => { - if (!locationsAreEqual(prevProps.to, location)) { + const prevLocation = + typeof prevProps.to === "string" + ? createLocation(prevProps.to) + : prevProps.to; + if ( + !locationsAreEqual(prevLocation, { + ...location, + key: prevLocation.key + }) + ) { method(location); } }} diff --git a/packages/react-router/modules/__tests__/Redirect-test.js b/packages/react-router/modules/__tests__/Redirect-test.js index dcee37c8d8..ceae6b98e9 100644 --- a/packages/react-router/modules/__tests__/Redirect-test.js +++ b/packages/react-router/modules/__tests__/Redirect-test.js @@ -1,7 +1,7 @@ import React from "react"; import ReactDOM from "react-dom"; import { MemoryRouter, Redirect, Route, Switch } from "react-router"; - +import { createLocation } from "history"; import renderStrict from "./utils/renderStrict"; describe("A ", () => { @@ -11,6 +11,31 @@ describe("A ", () => { ReactDOM.unmountComponentAtNode(node); }); + describe("that always renders", () => { + it("doesn't break / throw when rendered with string `to`", () => { + expect(() => { + renderStrict( + + + , + node + ); + }).not.toThrow(); + }); + + it("doesn't break / throw when rendered with location `to`", () => { + const to = createLocation("/go-out?search=foo#hash"); + expect(() => { + renderStrict( + + + , + node + ); + }).not.toThrow(); + }); + }); + describe("inside a ", () => { it("automatically interpolates params", () => { let params;