我猜这是 React 101 并且被问了很多次,但我看不出我做错了什么。
某些原因导致此代码进入无限渲染循环并崩溃。我怀疑 isLoggedIn 标志,但现在不太确定。x.loginSlice.isLoggedIn 是一个直接布尔值,它被设置在由 redux-toolkits createSlice helper 创建的 reducer 中。我认为它没有违反任何“不改变状态”规则。
我的假设是,只有当 useSelector 上的相等检查功能检测到 redux 存储发生变化时,才应该重新渲染。也许有别的东西在做?可能是位置?我仍然不知道究竟是如何通过反应路由器“神奇地”传递位置的。
谁能看到我做错了什么?
谢谢 :-)
const PrivateRoute: React.FC<{ path: string, exact: boolean, children: ReactNode }> = ({children, ...rest}) => {
const isLoggedIn = useSelector((x: RootState) => x.loginSlice.isLoggedIn, (x, y) => x===y)
console.log('rendering privateRoute')
return (
<Route
{...rest}
render={({location}) =>
isLoggedIn ? (
children
) : (
<Redirect
to={{
pathname: "/page/Login",
state: {from: location}
}}
/>
)
}
/>
);
}
const App: React.FC = () => {
core.RunSetup()
const darkMode = useAppSelector(x => x.settings.darkMode)
return (
<IonApp className={darkMode === 'dark' ? 'dark-theme' : ''}>
<IonReactRouter>
<IonSplitPane contentId="main">
<IonRouterOutlet id="main">
<Route path="/" exact={true}>
<Redirect to="/page/Login"/>
</Route>
<Route path="/page/:name" exact={true}>
<Page/>
</Route>
<PrivateRoute path="/study/Counter" exact={true}>
<LearningPageWrapper page={TestPages.counter}/>
</PrivateRoute>
</IonRouterOutlet>
<Menu/>
</IonSplitPane>;
</IonReactRouter>
</IonApp>
);
}
;
export default App;
其他资源
在阅读了一些评论后,我更深入地了解了正在呈现的其他页面。
根据反应分析器:
- “路由器”似乎是参与正在进行的渲染循环的最高级别组件
- 路由器的“为什么要渲染”是“状态已更改:位置”。我正在更多地研究路由器文档。
如果有帮助,我在这里分享了一些文件。包括崩溃期间的控制台日志、导出的反应分析器数据和所有 tsx 文件。我已经对后者进行了修改,以尝试使它们尽可能简约。
再次感谢你的帮助!尽管脱发,我觉得我在这里学到了一些重要的东西。
编辑2:它似乎工作,但我不知道为什么。
如果我删除state: {from: location}
问题似乎消失了。我不知道为什么,但请注意,即使在导航到page/login
应该只是一条正常路线时,这条 privateRoute 仍在呈现。我想知道这是否可能是原因。也许位置对象中不断变化的 pathName 正在更改传递给的道具PrivateRoute
并导致它进入无限循环。
无论如何 - 现在我没有被困住。如果有人想向我解释这一切,我会留下这个问题。