1

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);
Vishal Shetty
  • 1,198
  • 20
  • 33
  • Please post one of the components that looks "messed" - so for instance if the AboutUs page looks "messed" then please post the code to the AboutUs component. – Chris Cousins Jun 09 '18 at 15:04
  • please, provide a redirect logic, e.g. code where you are using – amankkg Jun 09 '18 at 15:07
  • 2
    Updated with the components and Login, It's not the only problem with , even if I use it has the same problem. There is go button in the menu of the website uses , check that the same problem exists. – Vishal Shetty Jun 09 '18 at 15:16
  • Seems like the issue is not with react-router or react at all, it's kind of jquery plugin or something that injects `div.paralax-mirror` nodes in `body` right before `div#root` node. I guess, it listens to `window.load` event or similar, which is why it is working OK on page reload and not reacting to dynamic changes after page is loaded. I suggest you revise the rest of non-react code. – amankkg Jun 09 '18 at 15:39
  • I am using a theme for this project, so not sure about the plugins and their working, but the div.paralax-mirror is already in the theme. But I guess, when I redirect to a new page, the already existing dom is mixed up with the new one, resulting it is messing everything. When we reload, it replaces the existing dom with the new one so everything is loading fine. – Vishal Shetty Jun 09 '18 at 15:55
  • Actually, react-router just replaces one DOM node with another, so there is nothing to be 'mixed up'. The problem is that once loaded, `div.paralax-mirror` is unaware of any new changes in the DOM. – amankkg Jun 09 '18 at 16:41

1 Answers1

2

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.

Vishal Shetty
  • 1,198
  • 20
  • 33