React 路由器重定向页面但组件未渲染

Nor*_*yan 3 reactjs react-router react-router-dom

当路由更改时,我在渲染组件时遇到了一个奇怪的问题。\n我使用的版本

\n\n
{\n  "react": "16.9.0",\n  "react-dom": "16.9.0",\n  "react-router-dom": "5.1.0"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的路线配置

\n\n
const Routes = () => {\n    const isLoggedIn = StorageManager.get(\'session\');\n    return (\n        <>\n            <div className="background"></div>\n            <MainLayout>\n                <Header />\n                <LeftSidebarMenu />\n                <main className="main-container">\n                    <Router history={history}>\n                        <Switch>\n                            <Redirect exact from="/" to="/categories" />\n                            <Route exact path=\'/categories\' component={Home} />\n                            <Route exact path=\'/categories/new\' component={CreateCategory} />\n                            <Route exact path=\'/login\' component={Login}\n                                />\n                        </Switch>\n                    </Router>\n                </main>\n            </MainLayout>\n        </>\n    );\n};\n\nexport default Routes;\n
Run Code Online (Sandbox Code Playgroud)\n\n

主要问题是,当用户单击登录/注销时,如果成功/失败,它应该将用户重定向到适当的页面。实际上路线发生了变化,但组件没有被渲染。我使用history.push(PATH)来重定向用户。我不是react初学者,说实话,我第一次遇到这种奇怪的问题。也许我把一些东西与我的路由器配置混淆了。

\n\n
import React, {useState} from \'react\';\nimport {withRouter, Link} from \'react-router-dom\';\nimport Modal from \'react-modal\';\nimport {shallowEqual, useSelector} from \'react-redux\';\nimport Button from \'../../components/core/button\';\nimport StorageManager from \'../../helpers/utilities/storageManager\';\nimport FormGroup from \'../../components/core/form/form-group\';\nimport useForm from \'../../helpers/custom-hooks\';\nimport {signInRequest} from \'../../redux/actions\';\n\nModal.setAppElement(\'#root\');\n\nconst Header = (props) => {\n    const actionResult = useSelector((state) => state.admin.actionResult, shallowEqual);\n\n    const {handleInputChange, handleSubmit} = useForm(signInRequest);\n    const [session, setSession] = useState(StorageManager.get(\'session\'));\n    const [isLoginModalOpen, toggleLoginModal] = useState(false);\n    const toggleModal = () => toggleLoginModal(!isLoginModalOpen);\n\n    const handleLogin = () => {\n        handleSubmit();\n    };\n\n    if(actionResult && actionResult.type === \'success\' && isLoginModalOpen){\n        setSession(StorageManager.get(\'session\'));\n        toggleLoginModal(false);\n        props.history.push(\'/categories\');\n    }\n\n    const handleLogout = () => {\n        props.history.push(\'/login\');\n        StorageManager.remove(\'session\');\n        // setSession(\'\');\n    };\n\n    return (\n        <header className="header-section clearfix">\n            <div className="header-container">\n                <div className="header-left-menu">\n                    <div className=\'header-logo-box\'>\n                        <a className="navbar-brand" href="#"><img src={require(\'../../images/logo.png\')} alt=""/></a>\n                    </div>\n                </div>\n                <Link to=\'/categories\'>Link</Link>\n                <div className="header-right-menu">\n                    <div className="user-settings">\n                        <img src={require(\'../../images/user.png\')} alt=""/>\n                        <span>Username</span>\n                        {\n                            session ?\n                            <Button\n                            className=\'btn-medium\'\n                            text=\'\xd0\x92\xd1\x8b\xd1\x85\xd0\xbe\xd0\xb4\'\n                            onClick={handleLogout}\n                        /> :\n                        <Button\n                            className=\'btn-medium\'\n                            text=\'\xd0\x9b\xd0\xbe\xd0\xb3\xd0\xb8\xd0\xbd\'\n                            onClick={toggleModal}\n                        />\n                        }\n                    </div>\n                </div>\n            </div>\n            <Modal\n                isOpen={isLoginModalOpen}\n                style={customStyles}\n                shouldCloseOnOverlayClick={true}\n                onRequestClose={toggleModal}\n                contentLabel="Login Modal"\n            >\n                <FormGroup className=\'form-group__modal\'>\n                    <h3>Login</h3>\n                    <input\n                        type="text"\n                        placeholder="login"\n                        name="login"\n                        className=\'form-input\'\n                        onChange={handleInputChange}\n                    />\n                    <h3>Password</h3>\n                    <input\n                        type="text"\n                        placeholder="password"\n                        name="password"\n                        className=\'form-input\'\n                        onChange={handleInputChange}\n                    />\n                    <Button\n                        text=\'Sign in\'\n                        onClick={handleLogin}\n                    />\n                    <div className=\'invalid\'>{actionResult ? actionResult.message : \'\'}</div>\n                </FormGroup>\n            </Modal>\n        </header>\n    );\n};\n\nexport default withRouter(Header);\n
Run Code Online (Sandbox Code Playgroud)\n

Shu*_*tri 5

您的代码中的问题是您希望执行操作的位置没有被路由器提供程序封装。即使您使用 withRouter (这是一个尝试从最近的路由提供商获取路由器道具的 HOC),它也不会从用于包装所有路由的路由器获取历史道具。

您需要更新如何使用 Router 包装组件,例如

const Routes = () => {
    const isLoggedIn = StorageManager.get('session');
    return (
        <>
           <div className="background"></div>
           <Router history={history}>
            <MainLayout>
                <Header />
                <LeftSidebarMenu />
                <main className="main-container">
                        <Switch>
                            <Redirect exact from="/" to="/categories" />
                            <Route exact path='/categories' component={Home} />
                            <Route exact path='/categories/new' component={CreateCategory} />
                            <Route exact path='/login' component={Login}
                                />
                        </Switch>
                </main>
            </MainLayout>
          </Router>
        </>
    );
};

export default Routes;
Run Code Online (Sandbox Code Playgroud)