React路由器重定向页面但组件没有被渲染 [英] React router redirects the page but component doesn't get rendered

查看:101
本文介绍了React路由器重定向页面但组件没有被渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Route 更改时渲染组件有一个奇怪的问题.我使用的版本

<代码>{反应":16.9.0","react-dom": "16.9.0",反应路由器-dom":5.1.0"}

这是我的路由配置

const Routes = () =>{const isLoggedIn = StorageManager.get('session');返回 (<><div className="background"></div><主布局><标题/><LeftSidebarMenu/><main className="main-container"><路由器历史={历史}><开关><完全重定向 from="/" to="/categories"/><路由精确路径='/categories' component={Home}/><路由精确路径='/categories/new' component={CreateCategory}/><路由精确路径='/login' component={Login}/></开关></路由器></main></MainLayout></>);};导出默认路由;

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

import React, {useState} from 'react';从 'react-router-dom' 导入 {withRouter, Link};从'react-modal'导入模态;从'react-redux'导入{shallowEqual,useSelector};从../../components/core/button"导入按钮;从 '../../helpers/utilities/storageManager' 导入 StorageManager;从'../../components/core/form/form-group'导入FormGroup;从'../../helpers/custom-hooks'导入useForm;从'../../redux/actions'导入{signInRequest};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 = () =>{处理提交();};if(actionResult && actionResult.type === 'success' && isLoginModalOpen){setSession(StorageManager.get('session'));切换登录模式(假);props.history.push('/categories');}const handleLogout = () =>{props.history.push('/登录');StorageManager.remove('session');//setSession('');};返回 (<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=""/></>

<Link to='/categories'>Link</Link><div className="header-right-menu"><div className="用户设置"><img src={require('../../images/user.png')} alt=""/><span>用户名</span>{会议 ?<按钮className='btn-medium'文字='Выход'onClick={handleLogout}/>:<按钮className='btn-medium'text='Логин'onClick={toggleModal}/>}

<模态isOpen={isLoginModalOpen}样式={自定义样式}shouldCloseOnOverlayClick={true}onRequestClose={toggleModal}contentLabel="登录模式"><FormGroup className='form-group__modal'><h3>登录</h3><输入类型=文本"占位符=登录"名称=登录"类名='表单输入'onChange={handleInputChange}/><h3>密码</h3><输入类型=文本"占位符=密码"名称=密码"类名='表单输入'onChange={handleInputChange}/><按钮文字='登录'onClick={handleLogin}/><div className='invalid'>{actionResult ?actionResult.message : ''}

</FormGroup></模态></标题>);};导出默认 withRouter(Header);

解决方案

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

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

const Routes = () =>{const isLoggedIn = StorageManager.get('session');返回 (<><div className="background"></div><路由器历史={历史}><主布局><标题/><LeftSidebarMenu/><main className="main-container"><开关><完全重定向 from="/" to="/categories"/><路由精确路径='/categories' component={Home}/><路由精确路径='/categories/new' component={CreateCategory}/><路由精确路径='/login' component={Login}/></开关></main></MainLayout></路由器></>);};导出默认路由;

I have a strange problem with rendering a component while Route changes. Versions I use

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

This is my route configuration

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;

The main problem is that, when a user clicks login/logout, in case of success/failure, it should redirect the user to the appropriate page. Actually the route changes, but the component doesn't get rendered. I use history.push(PATH) for redirecting users. I am not a beginner in react and to be honest, the first time I am faced with this kind of strange problem. Maybe I confused something with my router configs.

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);

解决方案

The problem in your code is that the place where you wish to take an action is not wrapped by a Router provider. Even if you use withRouter which is an HOC that tried to get the router props from the nearest provider of Routes, it won't get you the history props from your Router that is used to wrap all your Routes.

You need to update how you wrap your components with Router like

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;

这篇关于React路由器重定向页面但组件没有被渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆