Well, I'm using MERN stack to create a single-page app now. The Start MERN app that I clone from mern.io it contains a Posts example.
I don't know "need" What it is, It's used by PostDetailPage (at line 30) .
enter image description here
Just on a high level, need is generally used when you are doing server side rendering or isomorphic rendering.
One use is that it tells what data the component needs on mount.
So when doing SSR/ISR, the initial page that is rendered is setup by the server only.Whatever action defined in the
need is processed by the server.It is a way to tell the server that these are the things required to do before rendering the page.
May it be data fetching, updating reducers data.
Try to understand how Client Side/Server Side/Isomorphic rendering works.You will get better insight about it.
Related
TLDR: Is there a way to signal to NextJS to render a component only on the server (and thus only show the pre-rendered HTML on the client)?
Motivation:
The reason I want to do this is because the render function inside of the component in question runs a lot of (synchronous) Javascript. I'd like for this Javascript to not be included in the client bundle. My desired behavior is that this component is rendered once on the server and the generated HTML is simply displayed on the client; it should never render on the client.
Things that I've tried / don't work:
getServerSideProps
It appears that, even when a page has getServerSideProps, it will still send the Javascript code to the client. My assumption is that this occurs because NextJS (incorrectly) assumes that some state update could possibly occur in the component on the client and therefore the client must have access to the Javascript code to render the component in such an event. Perhaps I'm doing something wrong here?
Static rendering
The page uses dynamic from the URL (imagine something like the delivery status page of a delivery website; there are hundreds of thousands of different deliveries and so it doesn't make sense for them all to be statically rendered)
Conditional Rendering based on typeof window
I don't think this helps with my particular issue as I'd like to skip rendering entirely on the client but still show the component as it was rendered on the server
Thanks so much for any and all help!
Overview:
I got this route in my react application
example.com/routeName/:id
This is the entrypoint for my users, they click on the link and see a screen with informations provided by this hash in a right sidebar component.
example.com/routeName/94a31bb9-e6ae-4e9a-8749-0807f9efd0001
Below I attached a kind of wireframe, trying to be more clear about the sidebar:
Wireframe to understand how my app components are shown at the end, and why the hash is important in a visual way
This works fine, I can get the hash and make the request inside my dumb component to display data.
The problem:
I'm doing the fetch to the api in my Layout component, and passing down the data via props to my sidebar that is fixed in my layout, because it is displayed through all the user experience
When my user sign in, my route change, from:
example.com/routeName/94a31bb9-e6ae-4e9a-8749-0807f9efd0001
to:
example.com/nextRouteNameHere
I still see the component with the information I need, but if I refresh the page at the second route, the app crashes, because my sidebar cant find the hash to fetch my api and get the necessary data.
What I've been trying to do:
Persist this route with the hash and make the route change internally - but that doesn't makes sense to me at all, and I could not find any resources even close to this strategy.
Persist this hash in localstorage and get the hash with hooks inside the sidebar. This way if I can't find my hash at the url it'll be in the localstorage and I can fetch my api to get the data. I did it, but doesn't work because the components presents the some behavior, trying to render with no data.
As I'm using redux to manage the global state I've already taken the hash and the fetch response to the localstorage, this way I can take this data through all the aplication, but the hash is what makes my hooks update when I tried to wrote this strategy, and when the user updates the page I got the same behavior, because the hook could not find the :id on the url.
Final question
How can I persist the sidebar with the fetched data I did when I load the page?
NOTE
I did not post the code because at this moment I got too much code trying to solve this and I'm stuck in this problem for almost one month. I'll update this post later on.
I just have began to study ReactJS and found that it gives you 2 ways to render pages: server-side and client-side. But, I can't understand how to use it together. Is it 2 separate ways to build the application, or can they be used together?
If we can use it together, how to do it - do we need to duplicate the same elements on the server side and client side? Or, can we just build the static parts of our application on the server, and the dynamic parts on the client side, without any connection to the server side that was already pre-rendered?
For a given website / web-application, you can use react either client-side, server-side or both.
Client-Side
Over here, you are completely running ReactJS on the browser. This is the simplest setup and includes most examples (including the ones on http://reactjs.org). The initial HTML rendered by the server is a placeholder and the entire UI is rendered in the browser once all your scripts load.
Server-Side
Think of ReactJS as a server-side templating engine here (like jade, handlebars, etc...). The HTML rendered by the server contains the UI as it should be and you do not wait for any scripts to load. Your page can be indexed by a search engine (if one does not execute any javascript).
Since the UI is rendered on the server, none of your event handlers would work and there's no interactivity (you have a static page).
Both
Here, the initial render is on the server. Hence, the HTML received by the browser has the UI as it should be. Once the scripts are loaded, the virtual DOM is re-rendered once again to set up your components' event handlers.
Over here, you need to make sure that you re-render the exact same virtual DOM (root ReactJS component) with the same props that you used to render on the server. Otherwise, ReactJS will complain that the server-side and client-side virtual DOMs don't match.
Since ReactJS diffs the virtual DOMs between re-renders, the real DOM is not mutated. Only the event handlers are bound to the real DOM elements.
Image source: Walmart Labs Engineering Blog
NB: SSR (Server Side Rendering), CSR (Client Side Rendering).
The main difference being that with SSR, the servers response to the clients browser, includes the HTML of the page to be rendered.
It is also important to note that although, with SSR, the page renders quicker. The page will not be ready for user interaction until JS files have been downloaded and the browser has executed React.
One downside is that the SSR TTFB (Time to First Byte) can be slightly longer. Understandably so, because the server takes some time creating the HTML document, which in turn increases the servers response size.
I was actually wondering the same researching quite a bit and while the answer you are looking for was given in the comments but I feel it should be more prominent hence I'm writing this post (which I will update once I can come up with a better way as I find the solution architecturally at least questionable).
You would need to write your components with both ways in mind thus basically putting if switches everywhere to determine whether you are on the client or the server and then do either as DB query (or whatever appropriate on the server) or a REST call (on the client). Then you would have to write endpoints which generate your data and expose it to the client and there you go.
Again, happy to learn about a cleaner solution.
Is it 2 separate ways to build the application, or can they be used together?
They can be used together.
If we can use it together, how to do it - do we need to duplicate the
same elements on the server side and client side? Or, can we just
build the static parts of our application on the server, and the
dynamic parts on the client side, without any connection to the server
side that was already pre-rendered?
It's better to have the same layout being rendered to avoid reflow and repaint operations, less flicker / blinks, your page will be smoother. However, it's not a limitation. You could very well cache the SSR html (something Electrode does to cut down response time) / send a static html which gets overwritten by the CSR (client side render).
If you're just starting with SSR, I would recommend start simple, SSR can get very complex very quickly. To build html on the server means losing access to objects like window, document (you have these on the client), losing ability to incorporate async operations (out of the box), and generally lots of code edits to get your code SSR compatible (since you'll have to use webpack to pack your bundle.js). Things like CSS imports, require vs import suddenly start biting you (this is not the case in default React app without webpack).
The general pattern of SSR looks like this. An Express server serving requests:
const app = Express();
const port = 8092;
// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
console.log('fullUrl: ', fullUrl);
console.log('req.url: ', req.url);
// Create a new Redux store instance
const store = createStore(reducerFn);
const urlToRender = req.url;
// Render the component to a string
const html = renderToString(
<Provider store={store}>
<StaticRouter location={urlToRender} context={{}}>
{routes}
</StaticRouter>
</Provider>
);
const helmet = Helmet.renderStatic();
// Grab the initial state from our Redux store
const preloadedState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(helmet, html, preloadedState));
}
My suggestion to folks starting out with SSR would be to serve out static html. You can get the static html by running the CSR SPA app:
document.getElementById('root').innerHTML
Don't forget, the only reasons to use SSR should be:
SEO
Faster loads (I would discount this)
Hack : https://medium.com/#gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc
We are building our website with react/react-router/redux
We want to server side render our pages that should be filled by the data from our data sources. This transaction has to be asynchronous and unfortunately since we want to server side render, we can not use "componentDidMount" function.
In the redux tutorial page at server side rendering section here, it has been advised to :
If you use something like React Router, you might also want to express
your data fetching dependencies as static fetchData() methods on your
route handler components. They may return async actions, so that your
handleRender function can match the route to the route handler
component classes, dispatch fetchData() result for each of them, and
render only after the Promises have resolved. This way the specific
API calls required for different routes are colocated with the route
handler component definitions. You can also use the same technique on
the client side to prevent the router from switching the page until
its data has been loaded.
This is currently how we handle our data fetch. I personally did not like this approach it looks quite clumsy and it is too coupled to the routing library. Are there any better ways to do it - hopefully with standard react/router/redux components ?
Something like a static fetchData() method is the correct way to handle data fetching with React Router in the general case, though it can reach down into child components as needed (which is e.g. how Relay works).
The reason you want to do it this way is that React Router resolves all the matched routes all at once. Given that, you can then run data fetching for all of your route handlers simultaneously.
If instead you tied data fetching to instance-level handlers on components, you'd always end up with fetch waterfalls, where a component could not fetch its required data until all of its parents receive their required data, and so forth. While that may not be a big problem on the server, it's hugely suboptimal on the client.
If you really want to colocate data dependencies to components, you can consider using something like React Resolver, but this can easily lead to a suboptimal experience for your users.
I have a simple OAuth verification set up using Backbone, and it's working fairly well. My question is somewhat nitpicky (though... I am also new to Backbone), but I'm hoping to find somebody who might know how to solve this.
I have a Session model which, at initialization, sets a #authenticated value based on the presence of a value in localStorage. There's also a method in here, authenticate(), which checks the #authenticated value for pass/fail. If the value check fails, it uses my router to navigate to the login route. If the value check passes, an optional callback passed in by the user is run.
In my main AppView (the first View run at application start) I run Session.authenticate(), and if it passes, route to "#home" (and my Router handles loading additional Views).
My question is this: as an un-authenticated user, if I type http://url.com/#home into my browser, I am successfully routed to "#login", but if I bring up my DevTools, I can see a request being made for an image in my "HomeView" view. What am I not understanding about how Backbone flows through this process? Shouldn't the route for "#home" not even run until after the application initializes, and therefore not even attempting to load the "HomeView"?
What kind of templating engine are you using? If your templates are for instance inline, inside the HTML template where your backbone app lives, then I believe any images inside those are rendered when the page loads. I may be wrong. Also, ensure your HomeView is not running by logging something to the console in the view's initialize method.