React 路由器正在更改 URL 但未正确加载网页 [英] React router is changing the URL but not loading the webpage properly

查看:42
本文介绍了React 路由器正在更改 URL 但未正确加载网页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 React JS 项目,在该项目中我使用 React Router v4 创建客户端路由.

这是项目的实时网址:https://gokhana.herokuapp.com/

在主页上,客户将搜索城市/位置(仅限印度城市),只要客户选择位置(https://prnt.sc/jsy8rp),我想加载下一条路线,即https://gokhana.herokuapp.com/restaurants.

我正在使用 将页面重定向到 /restaurants 路由.

/restaurants 路由被加载时,页面没有正确加载,一切都乱七八糟.检查它是如何加载 https://prnt.sc/jsy96i

现在,如果我重新加载相同的 URL,页面会正确加载而没有任何问题 https://prnt.sc/jsya4t

使用 <Redirect/> 重定向到路由会产生问题,而重新加载相同的路由可以正常工作.

我已经检查了 CSS 和 JS 文件,所有这些文件都正确加载.

我无法弄清楚这个问题.

app.js 文件

从'react'导入React;从 'react-dom' 导入 ReactDOM;从'react-redux'导入{Provider};从./store"导入商店;从'jquery'导入$;导入 'bootstrap/dist/css/bootstrap.min.css';从./routes/AppRouter"导入路由器;//导入CSS文件导入'./styles/google-font.css';导入'./styles/base.css';ReactDOM.render(<提供者商店={商店}><路由器/></提供者>,document.getElementById('root'));

index.html 文件

<头><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>GoKhana</title><link rel="icon" type="image/png" href="./images/favicon.png"><link rel="stylesheet" type="text/css" href="./dist/styles.css"><身体><div id="root"></div><script src="https://code.jquery.com/jquery-2.2.4.min.js"></script><script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCmnIFpWp5ofkwDLZgCDLBat1VPEjOj_jA&libraries=places"></script><script src="./dist/bundle.js"></script><script src="./js/common_scripts_min.js"></script><script src="./js/functions.js"></script><script src="./js/modernizr.js"></script><script src="./js/cat_nav_mobile.js"></script><script>$('#cat_nav').mobileMenu();</script><script src="./js/ion.rangeSlider.js"></script><script src="./js/cat_nav_mobile.js"></script><script src="./js/theia-sticky-sidebar.js"></script><script src="./js/bootstrap3-wysihtml5.min.js"></script><script src="./js/dropzone.min.js"></script><script src="./js/tabs.js"></script><script src="./js/custom.js"></script></html>

AppRouter.js 文件

从'react'导入React;从react-router-dom"导入 {BrowserRouter, Route, Switch};从./../components/HomePage"导入主页;从./../components/AboutUs"导入关于我们;从'./../components/ContactUs'导入ContactUs;从'./../components/PageNotFound'导入PageNotFound;从'../components/RestaurantList'导入RestaurantList;从 '../components/RestaurantMenu' 导入 RestaurantMenu;从 '../components/UserDetails' 导入 UserDetails;从'../components/OrderConfirmation'导入订单确认;从 '../components/CustomerAccount' 导入 CustomerAccount;导出默认值 () =>{返回 (<浏览器路由器><开关><Route path="/" component={HomePage} exact={true}/><Route path="/about" component={AboutUs}/><Route path="/contact" component={ContactUs}/><Route path="/restaurants" component={RestaurantList}/><Route path="/select-menu" component={RestaurantMenu}/><Route path="/user-details" component={UserDetails}/><Route path="/order-confirmation" component={OrderConfirmation}/><Route path="/my-account" component={CustomerAccount}/><路由组件={PageNotFound}/></开关></BrowserRouter>);}

RestaurantList.js - 这个组件很乱

从'react'导入React;从'./sections/Header'导入标题;从'./sections/Footer'导入页脚;从 './sections/ImageSubHeader' 导入 ImageSubHeader;从./sections/Filters"导入过滤器;从./sections/DisplayRestaurants"导入 DisplayRestaurants;导出默认值 () =>{返回 (<div><标题/><ImageSubHeader title="搜索您最喜欢的餐厅" showSearch = "true"/><div className="容器边距_60_35"><div className="row"><过滤器/><展示餐厅/>

<页脚/>

);}

ImageSubHeader.js

 import React from 'react';从'./../../images/web-images/mainbanner.jpg'导入subHeaderImg;导出默认值(道具)=>{返回 (<section className="parallax-window" id="short" data-parallax="scroll" data-image-src={subHeaderImg} data-natural-width="1400" data-natural-height="350"><div id="子标题"><div id="sub_content"><h1>{props.title}</h1><p>{props.subTitle}</p>{props.showSearch &&(<form method="post" action="list_page.html"><div id="自定义搜索输入"><div className="输入组"><input type="text" className="search-query" placeholder="您的地址或邮政编码"/><span className="input-group-btn"><input type="submit" className="btn_search" value="submit"/></span>

</表单>)}{props.showOrder &&(<div className="bs-wizard"><div className={(props.orderId >=1) ?col-xs-4 bs-wizard-step 完成":col-xs-4 bs-wizard-step 已禁用"}><div className="text-center bs-wizard-stepnum"><strong>1.</strong>您的详细信息

<div className="progress"><div className="progress-bar"></div></div><a href="#0" className="bs-wizard-dot"></a>

<div className={(props.orderId >=2) ?col-xs-4 bs-wizard-step 完成":col-xs-4 bs-wizard-step 已禁用"}><div className="text-center bs-wizard-stepnum"><strong>2.</strong>付款

<div className="progress"><div className="progress-bar"></div></div><a href="cart_2.html" className="bs-wizard-dot"></a>

<div className={(props.orderId >=3) ?col-xs-4 bs-wizard-step 完成":col-xs-4 bs-wizard-step 已禁用"}><div className="text-center bs-wizard-stepnum"><strong>3.</strong>完成!

<div className="progress"><div className="progress-bar"></div></div><a href="cart_3.html" className="bs-wizard-dot"></a>

)}

</节>);}

Filters.js

从'react'导入React;导出默认值 () =>{返回 (<div className="col-md-3"><div id="filters_col">

<div className="filter_type"><h6>评分</h6><ul><li><label><input type="checkbox" className="icheck"/><span className="rating"><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i></span></label></li><li><label><input type="checkbox" className="icheck"/><span className="rating"><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star"></i></span></label></li><li><label><input type="checkbox" className="icheck"/><span className="rating"><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star"></i><i className="icon_star"></i></span></label></li><li><label><input type="checkbox" className="icheck"/><span className="rating"><i className="icon_star 投票"></i><i className="icon_star 投票"></i><i className="icon_star"></i><iclassName="icon_star"></i><i className="icon_star"></i></span></label></li><li><label><input type="checkbox" className="icheck"/><span className="rating"><i className="icon_star 投票"></i><i className="icon_star"></i><i className="icon_star"></i><i className="icon_star"></i><i className="icon_star"></i></span></label></li>

<div className="filter_type"><h6>选项</h6><ul className="nomargin"><li><label><input type="checkbox" className="icheck"/>Delivery</label></li><li><label><input type="checkbox" className="icheck"/>Take Away</label></li><li><label><input type="checkbox" className="icheck"/>距离10Km</label></li><li><label><input type="checkbox" className="icheck"/>距离5Km</label></li>

);}

DisplayRestaurants.js

从'react'导入React;从'./GridListRestaurant'导入GridListRestaurant;导出默认值 () =>{返回 (<div className="col-md-9"><div id="工具"><div className="row"><div className="col-md-3 col-sm-3 col-xs-6"><div className="styled-select"><select name="sort_rating" id="sort_rating"><option value="" selected>按排名排序</option><option value="lower">最低排名</option><option value="higher">最高排名</option></选择>

<GridListRestaurant/><GridListRestaurant/>

);}

重定向逻辑SearchLocationBar.js

从'react'导入React;从'react-redux'导入{connect};从'react-router-dom'导入{重定向};从'./../../actions/locationActions'导入{setLocation};从'./../../actions/loaderActions'导入{toggleLoader};class SearchLocationBar 扩展 React.Component {位置 = {}状态 = {重定向:假}componentDidMount() {let autocomplete = document.getElementById('autocomplete');让 GoogleMapsApi = new google.maps.places.Autocomplete((autocomplete), {类型:'(地区)',组件限制:{国家:'in'}});google.maps.event.addListener(GoogleMapsApi, 'place_changed', () => {this.location = {};const place = GoogleMapsApi.getPlace();this.location.latitude = place.geometry.location.lat();this.location.longitude = place.geometry.location.lng();place.address_components.forEach((address) => {if(address.types.includes('locality')) {this.location.city = address.long_name;} else if(address.types.includes('administrative_area_level_2')) {this.location.city = address.long_name;} else if(address.types.includes('administrative_area_level_1')) {this.location.state = address.long_name;}});this.props.setLocation(this.location);localStorage.setItem('location',JSON.stringify(this.location));this.setState({redirect: true});});}使成为() {返回 (<form autoComplete="off" method="post"><div id="自定义搜索输入"><div className="输入组"><输入类型=文本"className="搜索查询"placeholder="您的地址或邮政编码"id="自动完成"/>{this.state.redirect ?<重定向到='/restaurants'/>:''}<span className="input-group-btn"><input type="submit" className="btn_search" value="submit"/></span>

</表单>);}}const mapStateToProps = (状态) =>{返回状态;};const mapDispatchToProps = {设置位置,切换加载器};导出默认连接(mapStateToProps,mapDispatchToProps)(SearchLocationBar);

解决方案

经过大量研究,我找到了问题的答案.

在 React Router 中,如果我们重定向到新路由,则不会加载 JS 库.就我而言,我使用的是在页面加载完成后注入 HTML 元素的插件.

现在,react routing 不会加载页面,因为这里的一切都是虚拟 DOM,所以这里的解决方案是在路由完成后加载 JS 库.

所以我使用了 loadjs 包.

1) 安装

yarn 添加 loadjs

2) 导入

从'loadjs'导入loadjs;

3) 在 React 组件的 componentDidMount() 中调用

loadjs('./js/modernizr.js', () => {});

这将解决问题.

I am working on a React JS project, inside the project I am using React Router v4 to create a client-side route.

This is the project live URL: https://gokhana.herokuapp.com/

On the homepage, a customer will search for the city/location (Indian cities only), whenever customer will select the location (https://prnt.sc/jsy8rp), I want to load the next route i.e https://gokhana.herokuapp.com/restaurants.

I am using <Redirect /> for redirecting the page to /restaurants route.

When the /restaurants route is loaded, the page is not loading properly, everything is messed. Check this how it is loading https://prnt.sc/jsy96i

Now, if I reload the same URL, the page is loaded correctly without any problem https://prnt.sc/jsya4t

Redirecting to the route with <Redirect /> creates a problem, while reloading the same route works fine.

I have checked for CSS and JS files all of them are loading properly.

I am unable to figure out this issue.

app.js file

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import store from './store';

import $ from 'jquery';
import 'bootstrap/dist/css/bootstrap.min.css';

import Routers from './routes/AppRouter';

//Import CSS files
import './styles/google-font.css';
import './styles/base.css';

ReactDOM.render(
    <Provider store={store}>
        <Routers />
    </Provider>,
    document.getElementById('root')
);

index.html file

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>GoKhana</title>
        <link rel="icon" type="image/png" href="./images/favicon.png">
        <link rel="stylesheet" type="text/css" href="./dist/styles.css">
    </head>
    <body>
        <div id="root"></div>


        <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
        <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCmnIFpWp5ofkwDLZgCDLBat1VPEjOj_jA&libraries=places"></script>            
        <script src="./dist/bundle.js"></script>

        <script src="./js/common_scripts_min.js"></script>
        <script src="./js/functions.js"></script>
        <script src="./js/modernizr.js"></script>

        <script  src="./js/cat_nav_mobile.js"></script>
        <script>$('#cat_nav').mobileMenu();</script>
        <script src="./js/ion.rangeSlider.js"></script>
        <script src="./js/cat_nav_mobile.js"></script>
        <script src="./js/theia-sticky-sidebar.js"></script>

        <script src="./js/bootstrap3-wysihtml5.min.js"></script>
        <script src="./js/dropzone.min.js"></script>
        <script src="./js/tabs.js"></script>

        <script src="./js/custom.js"></script>
    </body>
</html>

AppRouter.js file

import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';

import HomePage from './../components/HomePage';
import AboutUs from './../components/AboutUs';
import ContactUs from './../components/ContactUs';
import PageNotFound from './../components/PageNotFound';
import RestaurantList from '../components/RestaurantList';
import RestaurantMenu from '../components/RestaurantMenu';
import UserDetails from '../components/UserDetails';
import OrderConfirmation from '../components/OrderConfirmation';
import CustomerAccount from '../components/CustomerAccount';

export default () => {
    return (
        <BrowserRouter>
            <Switch>
                <Route path="/" component={HomePage} exact={true}/>
                <Route path="/about" component={AboutUs} />
                <Route path="/contact" component={ContactUs} />
                <Route path="/restaurants" component={RestaurantList} />
                <Route path="/select-menu" component={RestaurantMenu} />
                <Route path="/user-details" component={UserDetails} />
                <Route path="/order-confirmation" component={OrderConfirmation} />
                <Route path="/my-account" component={CustomerAccount} />
                <Route component={PageNotFound} />
            </Switch>
        </BrowserRouter>
    );
}

RestaurantList.js - This component is messed

import React from 'react';

import Header from './sections/Header';
import Footer from './sections/Footer';
import ImageSubHeader from './sections/ImageSubHeader';
import Filters from './sections/Filters';
import DisplayRestaurants from './sections/DisplayRestaurants';

export default () => {
    return (
        <div>
            <Header />
            <ImageSubHeader title="Search your Favorite Restaurant" showSearch = "true" /> 

            <div className="container margin_60_35">
                <div className="row">
                    <Filters />
                    <DisplayRestaurants />
                </div>
            </div>

            <Footer />
        </div>
    );
}

ImageSubHeader.js

    import React from 'react';

    import subHeaderImg from './../../images/web-images/mainbanner.jpg';

    export default (props) => {
        return (
            <section className="parallax-window" id="short" data-parallax="scroll" data-image-src={subHeaderImg} data-natural-width="1400" data-natural-height="350">
                <div id="subheader">
                    <div id="sub_content">
                        <h1>{props.title}</h1>
                        <p>{props.subTitle}</p>
                        {props.showSearch && 
                            (<form method="post" action="list_page.html">
                                <div id="custom-search-input">
                                    <div className="input-group ">
                                        <input type="text" className=" search-query" placeholder="Your Address or postal code" />
                                        <span className="input-group-btn">
                                        <input type="submit" className="btn_search" value="submit" />
                                        </span>
                                    </div>
                                </div>
                            </form>)
                        }

                        {props.showOrder && 
                            (
                                <div className="bs-wizard">
                                    <div className={(props.orderId >=1) ? "col-xs-4 bs-wizard-step complete" : "col-xs-4 bs-wizard-step disabled"}>
                                        <div className="text-center bs-wizard-stepnum"><strong>1.</strong> Your details</div>
                                        <div className="progress"><div className="progress-bar"></div></div>
                                        <a href="#0" className="bs-wizard-dot"></a>
                                    </div>

                                    <div className={(props.orderId >=2) ? "col-xs-4 bs-wizard-step complete" : "col-xs-4 bs-wizard-step disabled"}>
                                        <div className="text-center bs-wizard-stepnum"><strong>2.</strong> Payment</div>
                                        <div className="progress"><div className="progress-bar"></div></div>
                                        <a href="cart_2.html" className="bs-wizard-dot"></a>
                                    </div>

                                    <div className={(props.orderId >=3) ? "col-xs-4 bs-wizard-step complete" : "col-xs-4 bs-wizard-step disabled"}>
                                        <div className="text-center bs-wizard-stepnum"><strong>3.</strong> Finish!</div>
                                        <div className="progress"><div className="progress-bar"></div></div>
                                        <a href="cart_3.html" className="bs-wizard-dot"></a>
                                    </div>  
                                </div>
                            )
                        }
                    </div>
                </div>
            </section>
        );
    }

Filters.js

import React from 'react';

export default () => {
    return (
        <div className="col-md-3">
            <div id="filters_col">
                <a 
                    data-toggle="collapse" 
                    href="#collapseFilters" 
                    aria-expanded="false" 
                    aria-controls="collapseFilters" 
                    id="filters_col_bt
                "> 
                Filters 
                    <i className="icon-plus-1 pull-right"></i>
                </a>

                <div className="collapse" id="collapseFilters">
                    <div className="filter_type">
                        <h6>Distance</h6>
                        <input type="text" id="range" value="" name="range" />
                        <h6>Type</h6>
                        <ul>
                            <li><label><input type="checkbox" checked className="icheck" />All <small>(49)</small></label></li>
                            <li><label><input type="checkbox" className="icheck" />American <small>(12)</small></label><i className="color_1"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Chinese <small>(5)</small></label><i className="color_2"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Hamburger <small>(7)</small></label><i className="color_3"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Fish <small>(1)</small></label><i className="color_4"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Mexican <small>(49)</small></label><i className="color_5"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Pizza <small>(22)</small></label><i className="color_6"></i></li>
                            <li><label><input type="checkbox" className="icheck" />Sushi <small>(43)</small></label><i className="color_7"></i></li>
                        </ul>
                    </div>
                    <div className="filter_type">
                        <h6>Rating</h6>
                        <ul>
                            <li><label><input type="checkbox" className="icheck" /><span className="rating">
                            <i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i>
                            </span></label></li>
                            <li><label><input type="checkbox" className="icheck" /><span className="rating">
                            <i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star"></i>
                            </span></label></li>
                            <li><label><input type="checkbox" className="icheck" /><span className="rating">
                            <i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star"></i><i className="icon_star"></i>
                            </span></label></li>
                            <li><label><input type="checkbox" className="icheck" /><span className="rating">
                            <i className="icon_star voted"></i><i className="icon_star voted"></i><i className="icon_star"></i><i className="icon_star"></i><i className="icon_star"></i>
                            </span></label></li>
                            <li><label><input type="checkbox" className="icheck" /><span className="rating">
                            <i className="icon_star voted"></i><i className="icon_star"></i><i className="icon_star"></i><i className="icon_star"></i><i className="icon_star"></i>
                            </span></label></li>
                        </ul>
                    </div>
                    <div className="filter_type">
                        <h6>Options</h6>
                        <ul className="nomargin">
                            <li><label><input type="checkbox" className="icheck" />Delivery</label></li>
                            <li><label><input type="checkbox" className="icheck" />Take Away</label></li>
                            <li><label><input type="checkbox" className="icheck" />Distance 10Km</label></li>
                            <li><label><input type="checkbox" className="icheck" />Distance 5Km</label></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    );
}

DisplayRestaurants.js

import React from 'react';
import GridListRestaurant from './GridListRestaurant';

export default () => {
    return (
        <div className="col-md-9">
            <div id="tools">
                <div className="row">
                    <div className="col-md-3 col-sm-3 col-xs-6">
                        <div className="styled-select">
                            <select name="sort_rating" id="sort_rating">
                                <option value="" selected>Sort by ranking</option>
                                <option value="lower">Lowest ranking</option>
                                <option value="higher">Highest ranking</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>

            <GridListRestaurant />
            <GridListRestaurant />

        </div>
    );
}

REDIRECT LOGIC SearchLocationBar.js

import React from 'react';
import {connect} from 'react-redux';
import {Redirect} from 'react-router-dom';

import {setLocation} from './../../actions/locationActions';
import {toggleLoader} from './../../actions/loaderActions';

class SearchLocationBar extends React.Component {
    location = {}
    state = {
        redirect : false
    }

    componentDidMount() {
        let autocomplete = document.getElementById('autocomplete');
        let GoogleMapsApi = new google.maps.places.Autocomplete((autocomplete), {
            types: '(regions)',
            componentRestrictions: {country: 'in'}
        });

        google.maps.event.addListener(GoogleMapsApi, 'place_changed', () => {
            this.location = {};
            const place = GoogleMapsApi.getPlace();
            this.location.latitude = place.geometry.location.lat();
            this.location.longitude = place.geometry.location.lng();

            place.address_components.forEach((address) => {
                if(address.types.includes('locality')) {
                    this.location.city = address.long_name;
                } else if(address.types.includes('administrative_area_level_2')) {
                    this.location.city = address.long_name;
                } else if(address.types.includes('administrative_area_level_1')) {
                    this.location.state = address.long_name;
                }

            });
            this.props.setLocation(this.location);
            localStorage.setItem('location',JSON.stringify(this.location));

            this.setState({redirect: true});
        });

    }
    render() {
        return (
            <form autoComplete="off" method="post">
                <div id="custom-search-input">
                    <div className="input-group ">
                        <input 
                            type="text" 
                            className=" search-query" 
                            placeholder="Your Address or postal code"
                            id="autocomplete"
                        />
                        {this.state.redirect ? <Redirect to='/restaurants' /> : ''}
                        <span className="input-group-btn">
                        <input type="submit" className="btn_search" value="submit" />
                        </span>
                    </div>
                </div>
            </form>
        );
    }
}

const mapStateToProps = (state) => {
    return state;
};

const mapDispatchToProps = {
    setLocation,
    toggleLoader
};

export default connect(mapStateToProps, mapDispatchToProps)(SearchLocationBar);

解决方案

After a lot of studies, I found the answer to my problem.

In React Router, if we redirect to the new route then JS libraries are not loaded. In my case, I was using the plugins which were injecting the HTML elements after the page load is complete.

Now, react routing will not load the page as everything here is virtual DOM, so the solution here was to load the JS libraries after routing is done.

So I used loadjs package.

1) Install

yarn add loadjs

2) Import

import loadjs from 'loadjs';

3) Call it in componentDidMount() of the React Component

loadjs('./js/modernizr.js', () => {});

and this will resolve the problem.

这篇关于React 路由器正在更改 URL 但未正确加载网页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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