Hi there,
Note: To quickly understand my issue you can read through the text and skip the code, the second time around you then read the code which interest you or all of it.
I am using SSR and I am rendering landing page on path="/" and this works fine before I try to render the page the user must see upon login. So on react router I have something like (only path="/" and {PublicMenu} are important):
export const Routes = () =>
<App>
<Route exact path="/" component={PublicMenu}/>
<Route path="/howItWorks" component={HowItWorks}/>
<Route path="/registerInfo" component={RegisterInfo}/>
<Route path="/login/:nextPage/:previousPage" component={Login}/>
.
.
.
</App>
On the {PublicMenu} component upon login I try to add the logic to render the page the user must see upon login; the result of this is the landing page is first rendered and then the login page is rendered hence the flickering. The landing page is rendered by SSR way before chrome debugging even gets a chance to step through the code.
Here is the App code as per react router above in case you are interested in the App code:
import React, { Component } from 'react' //PropTypes
import { Link } from 'react-router-dom'
import { withTracker } from 'meteor/react-meteor-data';
import Loadmang from './utilities/Loadmang';
class App extends Component {
render() {
if (self.props.page == "logout")
{
userId = Meteor.userId();
if (Meteor.isClient) {
Meteor.logout(function(err) {
if (!err)
{
localStorage.removeItem("isLoggedIn")
path = window.location.origin + "/"
window.location.replace(path);
//this.props.history.push("/");
//return;
}
});
return;
}
}
var children = this.props.children
if (this.props.user)
return (<div>
<nav className="navbar navbar-fixed-top navbar-color-on-scroll">
<div className="container">
<div className="collapse navbar-collapse" id="navigation-index">
<ul className="nav navbar-nav navbar-left mobile-nav">
<li class="nav-link"><Link to="/store">Menu</Link></li>
<li className="nav-link"><Link to="/howItWorks">How it works</Link></li>
<li className="nav-link"><Link to="/about">Contact us</Link></li>
</ul>
<ul className="nav navbar-nav navbar-left">
<li className="nav-link nav-li-dsn-L"><Link to="/store/knowYouBetterQuestionOptions/checkDetails">Profile</Link></li>
<li className="nav-link nav-li-dsn-L"><Link to="/logout">Logout</Link></li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li className="nav-li-dsn-M"><Link to="/store/knowYouBetterQuestionOptions/checkDetails">Profile</Link></li>
<li className="nav-li-dsn-M"><Link to="/logout">Logout</Link></li>
</ul>
<div className="clearfix">
</div>
</div>
</div>
</nav>
<div className="wrapper">
<div className="container">
<div className="main container-fluid">
<div className="space-65"></div>
<div className="row">
<div className="col-xs-10 col-xs-offset-1 col-lg-8 col-lg-offset-2">
{ children }
</div>
</div>
<div className="col-xs-10 col-xs-offset-1 col-lg-8 col-lg-offset-2">
</div>
</div>
</div>
</div>
</div>)
else
return (<div>
<nav className="navbar navbar-fixed-top navbar-color-on-scroll">
<div className="container">
<div className="collapse navbar-collapse" id="navigation-index">
<ul className="nav navbar-nav navbar-left mobile-nav">
<li className="nav-link"><Link to="/home">Home</Link></li>
<li className="nav-link"><Link to="/howItWorks">How it works</Link></li>
<li className="nav-link"><Link to="/about">Contact us</Link></li>
</ul>
<ul className="nav navbar-nav navbar-left">
<li className="nav-link nav-li-dsn-L"><Link to="/registerInfo">Register</Link></li>
<li className="nav-link nav-li-dsn-L"><Link to="/login/anonymousGenBody/anonymousGenBody">Login</Link></li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li className="nav-li-dsn-M"><Link to="/registerInfo">Register</Link></li>
<li className="nav-li-dsn-M"><Link to="/login/anonymousGenBody/anonymousGenBody">Login</Link></li>
</ul>
<div className="clearfix">
</div>
</div>
</div>
</nav>
<div className="wrapper">
<div className="container">
<div className="main container-fluid">
<div className="space-65"></div>
<div className="row">
<div className="col-xs-10 col-xs-offset-1 col-lg-8 col-lg-offset-2">
{ children }
</div>
</div>
<div className="col-xs-10 col-xs-offset-1 col-lg-8 col-lg-offset-2">
</div>
</div>
</div>
</div>
</div>)
}
}
export default withTracker( function(props) {
var user;
var group;
var groupMember;
var providers;
var customerAccount;
if (Meteor.isClient) {
const subscription = Meteor.subscribe('secondMemberId');
return {
loading1: !subscription.ready(),
user: Meteor.users.findOne({_id:Meteor.userId()})
}
}
else
{
return {
loading1: true,
user: user
}
}
})(App);
Here is the PublicMenu component code below. Please note that localStorage’s “isLoggedIn” in the code is set to “true” upon logging in - I have not pasted a snippet of that code. Note that if isLoggedIn was true when checked on the server there would be no flickering as both the client
and the server would have the exact same html rendered. Here is the PublicMenu code:
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { withTracker } from 'meteor/react-meteor-data';
//const PublicMenu = function() {
export class PublicMenu extends Component {
constructor(props){
super(props);
this.state = {
isLoggedIn : false
};
}
componentWillMount () {
var isLoggedIn;
if (Meteor.isClient)
isLoggedIn = localStorage.getItem("isLoggedIn");
if (isLoggedIn)
this.setState({isLoggedIn: true});
}
render() {
const self = this;
var isLoggedIn
if (this.state)
isLoggedIn = this.state.isLoggedIn;
if (isLoggedIn)
{
return (<div>
{Meteor.isClient
? <div>
<header>
<h1 className="header1">Menu</h1>
</header>
<div className="outerList">
<Link className="innerList anchor" to="/store/providerList">Data/Airtime/Electricity</Link>
<Link className="innerList anchor" to="/store/shareSchemeQuetion">Cash back program</Link>
<Link className="innerList anchor" to="/store/userBalance">Check balance</Link>
<Link className="innerList anchor" to="/store/knowYouBetterQuestionOptions/checkDetails">Profile</Link>
<Link className="innerList anchor" to="/store/searchPurchaseHistory">Purchase/Invoice history</Link>
<Link className="innerList anchor" to="/store/checkMemberId">Check member ID</Link>
<Link className="innerList anchor" to="/store/depositMoney">Deposit money</Link>
</div>
</div>
: <div>
<header>
<h1 className="header1">Menu</h1>
</header>
<div className="outerList">
<div className="innerList anchor" >Data/Airtime/Electricity</div>
<div className="innerList anchor" >Cash back program</div>
<div className="innerList anchor" >Check balance</div>
<div className="innerList anchor" >Profile</div>
<div className="innerList anchor" >Purchase/Invoice history</div>
<div className="innerList anchor" >Check member ID</div>
<div className="innerList anchor" >Deposit money</div>
</div>
</div>
}
</div>)
}
else
{
return (<div>
<header>
<h1 className="header1">Menu</h1>
</header>
{Meteor.isClient
? <div className="outerList">
<Link className="innerList anchor" to="/registerInfo">How?</Link>
<Link className="innerList anchor" to="/store/providerList">Data/Airtime/Electricity</Link>
<Link className="innerList anchor" to="/store/opened_discountsAccumulated">Funds Raised</Link>
<Link className="innerList anchor" to="/store/opened_userBalance">Check balance</Link>
<Link className="innerList anchor" to="/store/opened_searchPurchaseHistory">Purchase/Invoice history</Link>
<Link className="innerList anchor" to="/store/opened_checkDetails">Profile</Link>
<Link className="innerList anchor" to="/store/opened_checkStokvelId">Check group ID</Link>
<Link className="innerList anchor" to="/store/opened_stokvelMembers">Group members</Link>
<Link className="innerList anchor" to="/store/opened_depositMoney">Deposit money</Link>
<Link className="innerList anchor" to="/store/opened_checkBankDetails">Group bank details</Link>
<Link className="innerList anchor" to="/store/opened_membersToApproveBankDets">Members still to approve bank details</Link>
<Link className="innerList anchor" to="/store/opened_approveBankDetails">Approve Bank details</Link>
<Link className="innerList anchor" to="/store/opened_checkMemberId">Check member ID</Link>
<Link className="innerList anchor" to="/store/opened_deregisterFromGroup">Deregister from group</Link>
<Link className="innerList anchor" to="/store/opened_swapAdminRole">Swap admin role with another member</Link>
</div>
: <div className="outerList">
<div className="innerList anchor" >How?</div>
<div className="innerList anchor" >Data/Airtime/Electricity</div>
<div className="innerList anchor" >Funds Raised</div>
<div className="innerList anchor" >Check balance</div>
<div className="innerList anchor" >Purchase/Invoice history</div>
<div className="innerList anchor" >Profile</div>
<div className="innerList anchor" >Check group ID</div>
<div className="innerList anchor" >Group members</div>
<div className="innerList anchor" >Deposit money</div>
<div className="innerList anchor" >Group bank details</div>
<div className="innerList anchor" >Members still to approve bank details</div>
<div className="innerList anchor" >Approve Bank details</div>
<div className="innerList anchor" >Check member ID</div>
<div className="innerList anchor" >Deregister from group</div>
<div className="innerList anchor" >Swap admin role with another member</div>
</div>
}
</div>)
}
}
}
export default withTracker( function(props) {
var user;
var group;
if (Meteor.isClient) {
const subscription = Meteor.subscribe('secondMemberId');
return {
loading1: !subscription.ready(),
user: Meteor.users.findOne({_id:Meteor.userId()})
}
}
else
{
return {
loading1: true,
user: user
}
}
})(PublicMenu);
How can I render landing page and logged-in first page on path="/" without page flickering when using SSR? Please note that I rather have the server render the correct page followed by the same page by the client than suppress the server page and only have the client render the page. I saw that most people out there rather have the landing page be the same as the login first page to overcome this issue. Unfortunately that is not what my client wants, in fact I have different root path pages depending on the user’s role. Thanks for helping.