0

我猜这是 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并导致它进入无限循环。

无论如何 - 现在我没有被困住。如果有人想向我解释这一切,我会留下这个问题。

4

0 回答 0