ReactDOM renderToStaticMarkup renders <noscript></noscript> - node.js

I have a universal app with React Router.
let html = ReactDOM.renderToStaticMarkup(
<Provider store={store}>
<RoutingContext {...renderProps} />
</Provider>
);
The above is my React markup.
When I view my page source I see:
<div id="app">
<noscript></noscript>
<div id="home">
<h2>Home</h2>
</div>
</div>
What is this noscript tag? Can I get rid of it?

You seem to have confused Redux Router with React Router in the question.
The fragment of code you are running is for React Router, so I’ll assume that’s what you’re using.
React renders <noscript> for components that returned null during rendering.
Could it be that in your route configuration, there is no component matching that particular route?
Or that your component returned null?
It is hard to say more without seeing the full source code.

Related

Why cant my React App handle links to one of its routes?

Edit: For anyone coming here from Google, here is a TLDR: The reason for this "issue" is that React uses client side rendering. A quick solution is to use the HashRouter component, an SEO friendly solution is to use server side rendering(SSR). I switched to using NextJS, an SSR React framework, and my concern is resolved. Pages refresh like normal, and favorites work as intended. Thanks to all in the comments.
Original Question:
I've tried to find the answer to this but maybe i'm not googling well enough. So I have a react app with multiple routes, one of the routes is /reset, I have routing set up in the App.tsx like so:
import { BrowserRouter as Router, Link, Route, Switch} from 'react-router-dom';
class App extends Component<IAppProps, IAppState> {
constructor(props: IAppProps) {
super(props);
this.state = {
loggedin: "false",
user: {
username: "",
email: ""
}
};
}
<Router>
<nav className="topnav">
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About Us</Link></li>
<li><Link to="/faq">FAQ</Link></li>
<li><Link to="/login">Login</Link></li>
</ul>
</nav>
<Switch>
<Route exact path="/">
<Home
text="This text was passed in as a prop"
/>
</Route>
<Route path="/login">
<Login
changeHandler={this.updateLoginInput}
/>
</Route>
<Route path="/register">
<Register
formSubmit={null}
/>
</Route>
<Route path="/forgotpassword">
<ForgotPassword
stateSetter={this.handleChange}
/>
</Route>
<Route path="/reset">
<Home/>
</Route>
</Route>
</Switch>
</Router>
Sorry for the bad indenting, the editor doesn't like tabs.
The links work fine but, when ever i manually type in the address bar localhost:3000/reset it just keeps spinning and eventually times out. Same with every other route in fact. I need this to work because im sending a password reset email that will contain a link to use, and currently it just keeps spinning when the link is clicked. What if someone were to favorite a route on my page like mysite.com/page1? It would keep spinning and then eventually time out.
I've tried to add a route on the server side with app.get() and a response.redirect() and redirect to the reset route, but Chrome blocked it as an unsafe redirect.
Does this functionality not work on localhost or is there something else i'm doing wrong?

React js : Rendering multiple index html in a single page applications

I am developing an E - Commerce website in React and Node.js. I am facing two problems described below.
I have two different master .html files for admin side and front end side. Hence I am using builtin React admin template in which index.html is loading on project start. My problem is how can I load another master .html for front end design?
I want to use Node.js as the back end. Hence I can not integrate node.js with React front or admin side which will run if the React application runs.
Any suggestions or solution steps will be highly appreciated.
Here's a very basic concept of the first idea:
const AdminIndexPage = children => (<section className="AdminIndexPage">{children}</section>)
const PublicIndexPage = children => (<section className="PublicIndexPage">{children}</section>
const App = props => {
if(props.indexPageToShow === 'admin'){
return <AdminIndexPage {...props} />
}else{
return <PublicIndexPage {...props} />
}
}
Here's a very basic concept of the second idea:
index.html
<html>
<head>
<script src="index.js"></script>
</head>
<body>
<div id="AdminPageIndex"></div>
<div id="PublicPageIndex"></div>
</body>
</html>
index.js
import {AdminPageIndex, PublicPageIndex} from './pages'
ReactDOM.render(AdminPageIndex, document.getElementById('AdminPageIndex'))
ReactDOM.render(PublicPageIndex, document.getElementById('PublicPageIndex'))

Express not routing javascript files when URL has multiple directories

I'm setting up a server backend in express for a React application which is using React-Router v4. So far, I've set up Express so that any request is redirected to index.html, allowing React Router to do the rest of the work. This works for the routes '/beats', '/loops', '/kits', etc. The problem arises when there are multiple directories in the url, such as with the url '/beats/1/name-of-beat' (which is parsed as '/beats/:id/:name?' in react-router).
Using this express code:
app.use(express.static(path.join(__dirname, '../frontend/build')));
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, '../frontend/build/index.html'));
});
This will redirect all requests to /kit, /beats, and the like to index.html, and all the <script> sources will still work. However, when trying to reach '/beats/1/name', index.html is served, but the <script> tags are also served the index.html, resulting in index.html loading in the browser but none of the javascript.
This happens if I add any other directories to the url in addition to the first, so '/beats/example' or '/beats/1/2/3' but not for '/example' (which would correctly show the 404 configured in react-router).
If it's needed, here's the router code:
<Router>
<div className="App">
<Header />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/kits" component={Kits} />
<Route exact path="/beats" component={Beats} />
<Route path="/beats/:id/:beatName?" component={SoundPage} />
<Route path="/loops" component={Loops} />
<Route path="/contact" component={Contact} />
<Route component={NoMatch} />
</Switch>
</div>
</Router>
Here's the built index.html script tags:
<script src="./static/js/1.731b4af1.chunk.js"></script>
<script src="./static/js/main.498cadba.chunk.js"></script>
And here's the project structure:
-frontend
-build
-static
-index.html
-src
-public
-backend
-server.js
Long story short, your nested routes will need to use the match property. Your routes will be nested in a drop-down structure, where each successive Route will be included within the next matching Component's render method. Watch this video to understand what I mean:
React Router V4 Nested Routes
An alternative to using dynamic nested routes, would be to use a query parameter structure, where /beats/:query would be /beat/find?id=12345&beatName="Example Beat", which you can find an example here:
React Router V4 Nested Routes Match Params Not Accessible At Root Level
The first example is more common in forums (like Reddit), while the second example is more common in web store-fronts (like Amazon).

Handle Post request to React JS app

I have written a whole application in ReactJS Client Side. I am able to accept /API on my react app URL using <BrowserRouter>
I am looking for a way to make a post request to my React App. Eg. When a user makes a post request to http://myreactapp.com , it should recognize the Post request and get the Post Body received from this call and I want to assign it one of the state before the React App loads.
I tried searching many things on BrowserRouter but I am not able to find 1.
Can someone help me direct towards the way to implement handling POST with body params.
I am open to only suggestions too and and not the whole code since I am kind of stuck thinking what to do next.
render((
<BrowserRouter>
<div>
<Route exact path="/"
render={() => (<App />)} />
<Route path="/find/:find"
render={(props) => (<App {...props} />)} />
</div>
</BrowserRouter>
), document.getElementById('root')
);
I tried with BorwserRouter but it seems it only accepts Get parameters and not Post body.
I have also heard of using NodeJS or express as the backend but can someone help me with modifying my current React code to convert to Express only for Post request and remaining everything remains same,
TIA!

ComponentDidMount() in Server-side render

I'm trying to server-side render my webpage for better performance but am running into an issue where my page's components componentDidMount()s aren't getting called.
For example, this is my main template file:
import React from 'react';
import Cube from './components/Cube/Cube.jsx';
class Index extends React.Component {
render() {
return (
<html>
<head>
<title>{this.props.title}</title>
</head>
<body>
<Cube />
</body>
</html>
);
}
}
And my Cube.jsx:
import React from 'react';
class Cube extends React.Component {
componentDidMount() {
console.log("Hey!");
}
render() {
return (
<div>
<h1>Hello</h1>
</div>
);
}
}
export default Cube;
I'm not seeing "Hey!" getting logged out in my pm2 logs nor in my chrome console even though I'm seeing the <h1>Hello</h1> when the page loads. This is stopping me from having any sort of logic for my component.
How do I get around this problem and make my subcomponents's componentDidMount() get called? Note I'm using express-react-views for my server-side rendering.
I think the only lifecycle hook that will be called server side is componentWillMount as explained here
Even then you would not see output on Chrome's console. You are only likely to see it in your node logs.
Let me know if this answers your question.
Problem is as I my self found out few days ago using Next.js that React application is not mounted. What that means is that Server Side Rendering is exactly that. React app is 'rendered' aka static HTML file is created on the server, and served to the browser. But in that process React is not mounted and no hooks are fired. Maybe componentWillMount I am not sure and have not tested.

Resources