Is it possible to server side render only one component? - javascript

I have a react app which is rendered on the client side. Now I have a component which I want to render on the server side. I am doing this because the component will construct its layout from a json and I do not want to parse the json once on the server and again on the client to render the component.
Right now, I am doing renderToString(<Component/>) and sending it to the client. The client then does ReactDOM.hydrate(component,document.getElementById('someDivId')). But it only renders the component as a string. It is not rendering it as an element. The container on which I am trying to render the component is a client-side rendered react app.
Example code as below
server.js
app.get('/component/:id',(req,res,next)=>{
const markup = renderToString(
<div>Hello</div>
)
let jsonModel = {
markup
}
return res.json(jsonModel);
})
client.js
getComponent(id).then(data => {
ReactDOM.hydrate(data.markup, document.getElementById('someDivId'));
});
Is it possible to render only one component on the server side? Or do I have to render the whole app on the server side?

Related

What is optimal data flow between PHP backend and Vue frontend

I am wondering, what would be the best setup of data flow from PHP (database) to fronted Javascript rendering, lets say VueJS.
My first idea is, that will provide data attribute with JSON data to HTML element - div, which Vue instance will be mounted on.
I dont want to create REST API and load data via AJAX HTTP requests from Vue.
# PHP part
echo '<div id="myId" data-my-data="{h1:\"My heading\"}"></div>';
// Javascript part
import Vue from 'vue/dist/vue.js';
import App from './MyApp.vue';
const el = document.querySelector('#myId');
new Vue({
el,
render: h => h(App, {
props: {
myData: JSON.parse(el.dataset.myData),
},
}),
});
What do you think, is it ok or is there any other option except REST?
Update:
Main purpose is that my App will handle complex - multi-step Forms with some complex fields, which I would like to create as reusable components.
App will validate forms via AJAX (to prevent re-rendering page), on success redirect to success page.
My infrastructure would be, that PHP will prepare data, render main layout with assets (JS + CSS) and DIV with data atributes for Vue App.

Vue js dynamically loaded component name from ajax

I am new in vuejs . I want to load component from ajax response.
<div id="app"></div>
export default(){
created: function(){
const url = "xyz.json";
this.$http.get(url).then(response => {
this.resp = response.body;
var comp = this.resp.components;
}
}
}
Here is my JSON response
{
components: "Hello.vue",
}
I want to draw dynamically components by using json data
Update:
My Purpose is to draw a vuejs component in response of server side data. In server side data, I will tell which component will be loaded for this particular action. For example, I want to render particular view in response of drop-down value. If value is 1 , then server will tell load A component, if value is 2, then server will tell load B component.

Adding query parameters on form submission - React router 4

The desired effect when submitting a form using React router 4 is to append the search query to the end of the URL.
My current setup will send an API request on form submission, and then render the results in the render method.
Without using Links or Redirects, is there a way to add the query onto the URL, maybe from within the form submission method?
You can dynamically push the queries to the url like
this.props.router.push({
pathname: '/yourRoute',
query: { someQuery: 'value' }
})
Connect your Component with witRouter to be able to use the router prop
import { withRouter } from 'react-router'
....
export default withRouter(App);

Babel 6 + React - Passing initial data (In-browser transpiler)

I`m using React + Babel 6, with webpack.
When I was using Babel 5, it was easy to pass in the initial data using a script type="text/babel" on the page, then babel-core/browser.js takes care of it.
But now, using Babel 6, I have to load all the initial data calling the REST API, as my component mounts.
This results in the browser client opening a connection on the server to render the frontend, and then the frontend opens a new connection to get the data.
Wouldn't this affect my server performance as, now I have 2 connections vs the older 1 connection oppened?
EDIT:
I wish I could keep using the folowing snippet on the page:
<script type="text/javascript" src="{{ asset('app/bundle.js') }}"></script>
<script type="text/babel">
var jsonVar = '{vars}';
ReactDOM.render(
<App vars={vars}/>,
document.getElementById('app-wrapper')
);
</script>
It's a normal pattern to load your server side content and, then, your components grab some data. One downside of this design, of course, is that this implies one initial render plus api request for data.
However, you can setup a server side render with react components, rendering initial data on the server. If your backend is nodejs, for instance, you can use ReactDOMServer.renderToString.
I've resolved this issue by:
Using an "application/json" script tag(passing an id) and put serialized data inside it.
<script type="application/json" id="app-data"> { "id" : 1 } </script>
Then in the app.js:
var appData = JSON.parse( document.getElementById(script-id).innerHTML )

Render React JS server side using .net

I did the comments tutorial on http://reactjs.net/getting-started/tutorial.html and got it to render server side using .net mvc.
I have an existing mvc app where I rewrote a page in react. I'm trying to render it server side using .net but I get an error when it tries to render server side.
Exception Details: React.Exceptions.ReactServerRenderingException: Error while rendering "TopicAnswers" to "react1": TypeError: undefined is not a function
at React.createClass.render (Script Document [8]:80:39) -> var answerNodes = this.props.data.map(function(answer){
at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (Script Document [2]:7395:34)
Here's the code:
In my MVC view:
#Html.React("TopicAnswers", new
{
initialAnswers = Model,
url = Url.Action("TopicAnswers", new { id = ViewBag.TopicID }),
})
My TopicAnswers.jsx file:
var TopicAnswers = React.createClass({
getInitialState: function(){
alert('inside getInitialState: ' + this.props.initialAnswers);
return {answers: this.props.initialAnswers};
}
My ReactConfig.cs file:
ReactSiteConfiguration.Configuration
.AddScript("~/Scripts/internal/eusVote/TopicAnswers.jsx");
QUESTION: Why is it having a problem rendering the react file server side?
I got this error message trying to render React jsx file server side using .net:
"React.Exceptions.ReactServerRenderingException: Error while rendering "TopicAnswers" to "react1": TypeError: undefined is not a function"
My problem was that in the JSX file, I still had ComponentWillMount which called the loadAnswersFromServer. This is what you need if you are rendering client side. But once you adjust your code to render server side, you need to comment out/remove the ComponentWillMount so that it doesn't try to run the loadAnswersFromServer function on the server side.
With MVC, the data should be passed from the controller to the view and referenced in the #Html.Render("Comment", new { initialData = Model }) for the initial load.
Also, don't forget to comment out/remove the React.render( ... ) line from the JSX file.
alert is available only in browser window context. When rendering it on a server you can not call any functions that are browser related. If you are calling them, then you need to shim them so they are not failing on a server.

Categories