React router is changing the URL but not loading t

2019-08-18 22:10发布

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

1条回答
Root(大扎)
2楼-- · 2019-08-18 22:24

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.

查看更多
登录 后发表回答