Most basic way to execute ReactJs server side rendering - javascript

I want to make a very basic reactjs based application with server-side rendering to make sure the first load is quick and also to make sure all crawlers can access my content.
For this, I first followed the official reactjs docs and then looked for a basic routing option for my need. I ended up using React Router. Now, I want to enable server-side rendering for it without having to completely change this to use Redux or something. What would be the most basic/simplest way to do this.
The code in its present condition is as below:
import React from 'react'
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import './index.css';
//Product Image Component
class ProductImage extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 'https://rukminim1.flixcart.com/image/832/832/j8bxvgw0-1/mobile/g/j/z/mi-mi-mix-2-na-original-imaeydgnjzmvxwfz.jpeg?q=70',
alt: 'the product image'
};
}
render() {
return (
<div className="ProductImageContainer">
<img className="ProductImage"
src={this.state.value}
alt={this.state.alt}
/>
</div>
);
}
}
//Single Product Component
class ProductSingle extends React.Component {
render() {
return (
<div className="single">
<ProductImage />
</div>
);
}
}
//Homepage
class Home extends React.Component {
render() {
return (
<div>
<h2>Home</h2>
<p>The content is here.</p>
</div>
);
}
}
//About Page
class About extends React.Component {
render() {
return (
<div>
<h2>About</h2>
<p>The content is here.</p>
</div>
);
}
}
//Topic component
class Topic extends React.Component {
render() {
const {match} = this.props;
return (
<div>
<h3>{match.params.topicId}</h3>
</div>
);
}
}
//Topics component
class Topics extends React.Component {
render() {
const {match} = this.props;
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/rendering`}>
Rendering with React
</Link>
</li>
<li>
<Link to={`${match.url}/components`}>
Components
</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
<Route path={`${match.url}/:topicId`} component={Topic}/>
<Route exact path={match.url} render={() => (
<h3>Please select a topic.</h3>
)}/>
</div>
);
}
}
//Main App component
class App extends React.Component {
render() {
return (
<Router>
<div>
<ul className="menu">
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<Route exact path="/" component={Home}/>
<Route path="/about" component={ProductSingle}/>
<Route path="/topics" component={Topics}/>
</div>
</Router>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);

https://github.com/gzoreslav/react-redux-saga-universal-application/blob/master/README.md please check my repo. I used redux and redux-saga, but I guess you may replace them with another flux that you need

Related

React Router Link from another component wont work

so i had a navbar component that has a <Link></Link> inside of it the problem in i couldn't use that link for the router (it wont refresh) when i clicked on it although the link appears on the URL but it didn't refresh
here's the code
import React, { Component } from 'react'
import {BrowserRouter as Router} from 'react-router-dom'
import Route from 'react-router-dom/Route'
import Nav from './Nav'
export class App extends Component {
render() {
return (
<div className="App">
<Router>
{/* NAVBAR */}
<Nav />
<Route path="/" exact render={
() => <h1>home</h1>
}/>
<Route path="/about" exact render={
() => <h1>about</h1>
}/>
<Route path="/author" exact render={
() => <h1>author</h1>
}/>
</Router>
</div>
)
}
}
export default App
and here's the navbar code
import React, { Component } from 'react'
import styles from './Nav.module.css'
import {BrowserRouter as Router} from 'react-router-dom'
import {Link} from 'react-router-dom'
export class Nav extends Component {
render() {
return (
<Router>
<div className={styles.nav}>
<div className="container">
<div className={styles.navgrid}>
<img className={styles.image} src="/img/actualLogo#1x.svg" alt="?"/>
<ul className={styles.ultest}>
<li><Link to="/">Home</Link></li>
<li><Link to="/updates">Updates</Link></li>
<li><Link to="/author">Author</Link></li>
</ul>
</div>
</div>
</div>
</Router>
)
}
}
export default Nav
I'm assuming it's because it's not on the same <Router></Router> but does anyone have a way to make this work?
You're creating a new <Router>, which has no defined <Route> elements within it. Remove that router:
export class Nav extends Component {
render() {
return (
<div className={styles.nav}>
<div className="container">
<div className={styles.navgrid}>
<img className={styles.image} src="/img/actualLogo#1x.svg" alt="?"/>
<ul className={styles.ultest}>
<li><Link to="/">Home</Link></li>
<li><Link to="/updates">Updates</Link></li>
<li><Link to="/author">Author</Link></li>
</ul>
</div>
</div>
</div>
)
}
}
Each component doesn't need its own <Router>, as long as they're all contained within (descendants of) the one defined in <App>.

Rendering nested router view without parent router view - React.js

Hello community :) My first Q here.
(There were couple of similar questions but they didn't answer my particular code issue and I tried them to apply but without success.)
So I would like to render the child component in nested route without the parent one showing in the view
See the picture at the end --->
import React from 'react';
import {BrowserRouter, Route, Switch, Link} from "react-router-dom";
import 'bootstrap/dist/css/bootstrap.min.css';
import Routing from "./components/Routings";
export default class Browserrouting extends React.Component {
render () {
return (
<BrowserRouter>
<Routing/>
</BrowserRouter>
)
}
}
Here is the Routing component :
import About from "../views/About";
import HomeBackground from "../views/Background";
import ShelterApp from '../views/ShelterApp';
export default (props) => (
<div className="flexColumn">
<div> <ul className="flexRow center">
<li className="homeLink"><Link className="colorBrown" to="/">Home</Link></li>
<li className="homeLink"><Link className="colorBrown" to="/shelterApp">Shelter App</Link></li>
<li className="homeLink"><Link className="colorBrown" to="/about">About our site and shelter</Link></li>
</ul></div>
<Switch>
<Route exact path="/" component={() => <HomeBackground />} />
<Route path="/about" component={() => <About />} />
<Route path="/shelterApp" component={() => <ShelterApp />} />
</Switch>
</div>
)
And in ShelterApp component I have some text and imported another component which contains the links and nested routes I would like to display without showing the parent component ShelterApp:
class ShelterApp extends React.Component {
render() {
return (
<div className="flex center">
<div className="card center" style={{ "width": "25em", "height":"25em" }}>
<div className="card-body textCenter">
<h5 className="card-title paddingTitle">Welcome to our site</h5>
<h6 className="card-subtitle mb-2 text-muted"> Login or register if it's your first time</h6>
</div>
<LoginRouting match={this.props.match} />
</div>
</div>)
}
}
export default ShelterApp;
and the final child componet with the "lowest" routes in hierarchy :
class LoginRouting extends React.Component {
constructor(props) {
super(props)
this.state = {
users: []
}
}
static propTypes = {
match: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
history: PropTypes.object.isRequired
};
render() {
const { match, location, history } = this.props;
return (
<div >
<div className="flexRow center">
<Button className={" loginRouting"} type={"button"} bootstrapClass={"btn btn-light"} child={<Link to="/shelterApp/login">Login form</Link>} />
<Button className={" loginRouting"} type={"button"} bootstrapClass={"btn btn-light"} child={<Link to="/shelterApp/register">Register form</Link>} />
</div>
<div>
<Route path="/shelterApp/login" render={() => <Login />} />
<Route path="/shelterApp/register" render={() => <Register />} />
</div>
</div>
)
}
}
export default withRouter( LoginRouting)
enter image description here
IMAGE with the view :
I will be thankful for any advises !
On your ShelterApp component you can create a new state called hideInfo, or something, that tracks if the user clicked on "Login form" or "Register form".
Then you can pass a props to your <LoginRouting> component.
When the user clicks on "Login form" or "Register form" you change this.hideInfo.
<LoginRouting
onShowForm={() => this.setState({ hideInfo: !hideInfo})}
match={this.props.match}
/>

React.js Route - previous page stays after redirection

js and am using react-router-dom.
Say I have 2 files - 1. dashboard.js file
import React, { Component } from 'react';
import {Switch, Route, Link} from 'react-router-dom';
import WYSIWYG from './editor/wysiwyg';
export default class Dashboard extends Component{
render(){
return(
<div className="wrapper">
<Switch>
<Route exact path="/wysiwyg" component={WYSIWYG}/>
</Switch>
<ul id="DASHBOARD-MENU">
<li><Link to={{ pathname: '/wysiwyg'}}>WYSIWYG</Link></li>
</ul>
</div>
);
}
}
Note the ul with id="DASHBOARD-MENU" above
2nd - wysiwyg.js file
import React, { Component } from 'react';
export default class Wysiwyg extends Component{
render(){
return(
<div id="WYSIWYG-CONTAINER">
</div>
);
}
}
Note the div with id="WYSIWYG-CONTAINER" in the above snippet
My problem is:
After redirection to WYSIWYG container from my dashboard, I can still see the - <ul id="DASHBOARD-MENU" .. rendered below the <div id="WYSIWYG-CONTAINER ...
What I understood - is the component WYSIWYG is rendered replacing <Route declared in my dashboard.js file.
What I want:
I don't want the "DASHBOARD-MENU" element to render in my "WYSIWYG" page.
Is it possible?
The desired behavior can be obtained by considering both as different routes, and hence rendering only one of them depending on the path:
import React, { Component } from 'react';
import {Switch, Route, Link} from 'react-router-dom';
import WYSIWYG from './editor/wysiwyg';
const Dashboard = () => (
<ul id="DASHBOARD-MENU">
<li><Link to={{ pathname: '/wysiwyg'}}>WYSIWYG</Link></li>
</ul>
);
export default class Dashboard extends Component{
render(){
return(
<div className="wrapper">
<Switch>
<Route exact path="/" component={Dashboard} />
<Route exact path="/wysiwyg" component={WYSIWYG}/>
</Switch>
</div>
);
}
}

Can you search directly in the URL with react-router-dom?

The problem is that when I try to copy a route directly I get this error:
Cannot Get / home
But when I navigate with the menu items I usually render the views, I have tried several ways as browserHistory to achieve that effect but I do not succeed, I wonder, if react-router-dom does not allow navigation directly in the URL or is it an error in my code:
// Dependencies
import React, { Component} from 'react'
import { render } from 'react-dom'
import { BrowserRouter as Router, Route, browserHistory, Link} from 'react-router-dom'
//components
class App extends Component{
render(){
return(
<div>
<h1>App!</h1>
<ul>
<li><Link to="/home"> Home</Link></li>
<li><Link to="/about"> About </Link></li>
<li><Link to="/contact"> Contact </Link></li>
</ul>
</div>
)
}
}
class Home extends Component {
render() {
return(
<h2>Home Page!</h2>
)
}
}
class About extends Component{
render() {
return(
<h2>About Page!</h2>
)
}
}
class Contact extends Component {
render() {
return(
<h2>Contact Page!</h2>
)
}
}
// routes
render(
<Router history={browserHistory}>
<div>
<Route component={App} path="/" />
<Route component={Home} path="/home" />
<Route component={About} path="/about" />
<Route component={Contact} path="/contact" />
</div>
</Router>,
document.getElementById('app')
);
I have solved it! for those who have the same error, I share what I did;    to see the problem if it was from the server so I had to configure webpack with "historyApiFallback: true" or put  "--historyApiCallback" in the script of webpack dev server in the package.json luck :)

React Router - Nested Components will not Render

I have a standard react component created with create-react-app. I am trying to render different components using Links.
Here is my App.js:
import React, { Component } from 'react';
import { Router, Route, browserHistory } from 'react-router'
import Header from './Header';
import One from './One';
import Two from './Two';
import Three from './Three';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<div className="App">
<Router history={browserHistory} >
<Route component={Header} path="/" >
<Route component={One} path="one" name="One" />
<Route component={Two} path="two" name="Two" />
<Route component={Three} path="three" name="Three" />
</Route>
</Router>
</div>
);
}
}
export default App;
Here is the Header.js:
import React, { Component } from 'react';
import { Link } from 'react-router'
import './App.css';
class Header extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/one">One</Link></li>
<li><Link to="/two">Two</Link></li>
<li><Link to="/three">Three</Link></li>
</ul>
);
}
}
export default Header;
Here is One.js
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<h1>One</h1>
);
}
}
export default App;
I click on one of the links, the address bar changes, but no components will render inside of the nested route. I can remove the nesting:
<Router history={browserHistory} >
<Route component={Header} path="/" />
<Route component={One} path="one" name="One" />
<Route component={Two} path="two" name="Two" />
<Route component={Three} path="three" name="Three" />
</Router>
Which will render the components but the Header is no longer rendered.
What am I missing?
You forgot this part in Header component:
this.props.children
You need to define the place where you want to render your child components, Use this:
render() {
return (
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/one">One</Link></li>
<li><Link to="/two">Two</Link></li>
<li><Link to="/three">Three</Link></li>
</ul>
{this.props.children}
</div>
);
}

Categories