jsXpress is middleware for express/connect that allows for server-side rendering of elements written in react.
JSX Syntax
The examples below are written using JSX syntax, but OTHER SYNTAX should work perfectly fine.
If you would like to work with JSX syntax, there are many WAYS TO DO IT
Installation
To install jsxpress in your local project, simply type
npm install --save jsxpress
To reference jsxpress in your project
var jsXpress =require('jsxpress');
Getting Started
Using jsXpress with an express or connect application is easy. Simply place it on a route where you would normally place and pass it a react element.
var React =require('React');
var app =require('express')();
...
app.get('*',jsXpress(
<html renderat='/'>
<body>
Hello World
</body>
</html>
)
Notice the renderat attribute. It's set to '/', which means that the given component will render at the root of your application. If you were to leave this out, you application would not render.
If you wanted to have a choice between pages, you could put two element with the renderat attribute set side by side. Since you react requires adjacent components to be nexted, you'll have to wrap them in another element, but as long as it doesn't have a renderat attribute, it won't render.
app.get('*',jsXpress(
<html>
<html renderat='/'>
<body>
Hello World
</body>
</html>
<html renderat='/signin'>
<body>
Sign In
</body>
</html>
</html>
);
It won't really affect how your code works, but if you're uncomfortable using react components in such a way, you can use the jsXpress.NoRender component instead.
app.get('*',jsXpress(
<jsXpress.NoRender>
<html renderat='/'>
<body>
Hello World
</body>
</html>
<html renderat='/signin'>
<body>
Sign In
</body>
</html>
</jsXpress.NoRender>
);
Using Custom Components
You can easily use mix and match components, even custom ones.
classSignInPageextendsReact.Component{
constructor(){
}
render(){
<html renderat='/signin'>
<body>
Sign In
</body>
</html>
}
}
app.get('*',jsXpress(
<jsXpress.NoRender>
<html renderat='/'>
<body>
Hello World
</body>
</html>
<SignInPage renderat='signin'/>
</jsXpress.NoRender>
);
Prerendering elements
The rendering of elements can be pre-empted by assiging a function with a prerender attribute. The function has access to the element, the httprequest, and the http response. It should return a modified copy of the element to be rendered.
<AboutPage renderat='team' text='Who we are... '></AboutPage>
<AboutPage renderat='whatwedo' text='What we do...'></AboutPage>
</jsXpress.NoRender>
</jsXpress.NoRender>
);
Here, a page showing 'What we do' can be found by visiting /about/whatwedo
Route Parames
Route params are available as well. You can make them accessible in the request object during the prerender stage, by passing in the routeParams option.
varnameRenderer=function(element,request){
returnReact.cloneElement(
element,
{text :"Your name is "+request.routeParams.name}} +".");
You can use other just like you would in any other connect or express application. Because the request, response, and next objects from the express/connect router are attached to each components props object when rendering, JSX component can act like middleware by manipulating these in
their constructors.
classLoggerMiddleware Extends React.Component{
constructor(props){
var request =props.request;
var response =props.response;
var next =props.next();
console.log('Someone requested %.', request);
next();
}
render(){
return<a/>
}
}
//Note that even though the middleware element isn't rendered, React
//still requires components to have render methods that return components
If you do not wish to respond immediately, the prerender function can return a theanable to be fulfilled with a renderable component later. Set the renderThennable option to true to enable this.
varnameRenderer=function(element,request){
returnnewPromise(){
setTimeout(function(){
fulfill(React.cloneElement(
element,
{text :"Your name is "+request.routeParams.name}} +".");)
If you're rendering html for dymanic sites that will use react on the front end, you can render them with react-binding for better startup time. You do this by setting the dynamic option to true.