我猜这是 React 101 并且被问了很多次,但我看不出我做错了什么。
某些原因导致此代码进入无休止的渲染循环并崩溃。我怀疑是 isLoggedIn 标志,但现在不太确定。 x.loginSlice.isLoggedIn 是一个直接的布尔值,它被设置在由 redux-toolkits createSlice helper 创建的 reducer 中。我认为它没有违反任何“不改变状态”规则。
我的假设是,只有当 useSelector 上的相等检查函数检测到 redux 存储中的更改时,才应重新渲染。也许还有其他事情在做?大概位置?我仍然不清楚位置是如何通过 react-router“神奇地”传递的。
谁能看出我做错了什么?
谢谢:-)
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;
其他资源
在阅读了一些评论后,我更深入地了解了正在呈现的其他页面。
根据反应分析器:
如果有帮助,我已经分享了一些文件 here。包括崩溃期间的控制台日志、导出的反应分析器数据和所有 tsx 文件。我已经对后者进行了修改,以尝试使它们尽可能简约。
再次感谢您的帮助!尽管脱发,但我觉得我在这里学到了一些重要的东西。
如果我删除 state: {from: location}
,问题似乎就会消失。我不知道为什么,但请注意,即使导航到 page/login
这应该只是一条普通路线,此 privateRoute 仍在呈现。
我想知道 this 是否可能是原因。也许 location 对象中不断变化的 pathName 正在改变传递给 PrivateRoute
的 props 并导致它进入无限循环。
无论如何 - 现在我没有被困住。如果有人想向我解释这一切,我会留下这个问题。