【问题标题】:React router redirects the page but component doesn't get renderedReact路由器重定向页面但组件没有被渲染
【发布时间】:2020-03-04 20:05:11
【问题描述】:

我在 Route 更改时渲染组件时遇到了一个奇怪的问题。 我使用的版本

{
  "react": "16.9.0",
  "react-dom": "16.9.0",
  "react-router-dom": "5.1.0"
}

这是我的路线配置

const Routes = () => {
    const isLoggedIn = StorageManager.get('session');
    return (
        <>
            <div className="background"></div>
            <MainLayout>
                <Header />
                <LeftSidebarMenu />
                <main className="main-container">
                    <Router history={history}>
                        <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>
                    </Router>
                </main>
            </MainLayout>
        </>
    );
};

export default Routes;

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

import React, {useState} from 'react';
import {withRouter, Link} from 'react-router-dom';
import Modal from 'react-modal';
import {shallowEqual, useSelector} from 'react-redux';
import Button from '../../components/core/button';
import StorageManager from '../../helpers/utilities/storageManager';
import FormGroup from '../../components/core/form/form-group';
import useForm from '../../helpers/custom-hooks';
import {signInRequest} from '../../redux/actions';

Modal.setAppElement('#root');

const Header = (props) => {
    const actionResult = useSelector((state) => state.admin.actionResult, shallowEqual);

    const {handleInputChange, handleSubmit} = useForm(signInRequest);
    const [session, setSession] = useState(StorageManager.get('session'));
    const [isLoginModalOpen, toggleLoginModal] = useState(false);
    const toggleModal = () => toggleLoginModal(!isLoginModalOpen);

    const handleLogin = () => {
        handleSubmit();
    };

    if(actionResult && actionResult.type === 'success' && isLoginModalOpen){
        setSession(StorageManager.get('session'));
        toggleLoginModal(false);
        props.history.push('/categories');
    }

    const handleLogout = () => {
        props.history.push('/login');
        StorageManager.remove('session');
        // setSession('');
    };

    return (
        <header className="header-section clearfix">
            <div className="header-container">
                <div className="header-left-menu">
                    <div className='header-logo-box'>
                        <a className="navbar-brand" href="#"><img src={require('../../images/logo.png')} alt=""/></a>
                    </div>
                </div>
                <Link to='/categories'>Link</Link>
                <div className="header-right-menu">
                    <div className="user-settings">
                        <img src={require('../../images/user.png')} alt=""/>
                        <span>Username</span>
                        {
                            session ?
                            <Button
                            className='btn-medium'
                            text='Выход'
                            onClick={handleLogout}
                        /> :
                        <Button
                            className='btn-medium'
                            text='Логин'
                            onClick={toggleModal}
                        />
                        }
                    </div>
                </div>
            </div>
            <Modal
                isOpen={isLoginModalOpen}
                style={customStyles}
                shouldCloseOnOverlayClick={true}
                onRequestClose={toggleModal}
                contentLabel="Login Modal"
            >
                <FormGroup className='form-group__modal'>
                    <h3>Login</h3>
                    <input
                        type="text"
                        placeholder="login"
                        name="login"
                        className='form-input'
                        onChange={handleInputChange}
                    />
                    <h3>Password</h3>
                    <input
                        type="text"
                        placeholder="password"
                        name="password"
                        className='form-input'
                        onChange={handleInputChange}
                    />
                    <Button
                        text='Sign in'
                        onClick={handleLogin}
                    />
                    <div className='invalid'>{actionResult ? actionResult.message : ''}</div>
                </FormGroup>
            </Modal>
        </header>
    );
};

export default withRouter(Header);

【问题讨论】:

  • 你错过了第二个路由标签中的“/”,它应该是/categories/new
  • 那只是一个错字。实际问题与它无关
  • 对您从Switch 内的所有路由中删除exact 有帮助吗?
  • 你有没有试过在地址栏中手动写下这条路线,不管它是否有效?
  • 当它重定向时,它只在刷新后呈现该页面。我的组件甚至没有安装。是的,如果手动输入,它会重新加载页面并且一切正常

标签: reactjs react-router react-router-dom


【解决方案1】:

您的代码中的问题是您希望执行操作的位置没有被路由器提供程序包装。即使您使用 withRouter,它是一个 HOC,它试图从最近的 Routes 提供者那里获取路由器 props,它也不会从用于包装所有 Routes 的 Router 获取历史 props。

您需要更新使用 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;

【讨论】:

    猜你喜欢
    • 2020-11-25
    • 1970-01-01
    • 2018-12-13
    • 2017-12-20
    • 1970-01-01
    • 2020-07-01
    • 2020-09-20
    • 2021-02-25
    • 2020-07-05
    相关资源
    最近更新 更多