react-laravel icon indicating copy to clipboard operation
react-laravel copied to clipboard

Usage with redux

Open aprilmintacpineda opened this issue 8 years ago • 0 comments

app.js (entry point for elixir)

window.Layout = require('./components/Layout');

index.blade.php

<!DOCTYPE html>
<html>
<head>
	<title>React Laravel</title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">
</head>
<body>
	<div id="app">
		@if (!empty($prerender))
			@foreach($prerender as $index => $value)
				@react_component($value['component'], $value['data'])
			@endforeach
		@endif
	</div>
	<script type="text/javascript" src="{{ asset('js/app.js') }}"></script>
</body>
</html>

indexController

Controller for the Catch-all route, which has only one function.

    public function capture ($slug) {
    	$prerender = [
    		[
    			'component' => 'Layout',
    			'data' => [
    				'predata' => 'this is a predata',
    				'people' => [
						[
							'id' => 1,
							'name' => 'April Pineda',
							'age' => '21'
						],

						[
							'id' => 2,
							'name' => 'Kathy Singson',
							'age' => 37
						],

						[
							'id' => 3,
							'name' => 'Cyrine Julianne Pineda',
							'age' => 15
						]
					]
    			]
    		]
    	];

    	return view(
    		'index',
    		[
    			'prerender' => $prerender
    		]
    	);
    }

Layout.js (inside components directory)

const React = require('react');
const People = require('./People');

const Layout = React.createClass({
	render () {
		return (
			<div>
				<h1>Hello World!</h1>
				<p>{this.props.predata}</p>

				<People people={this.props.people}/>
			</div>
		);
	}
});

module.exports = Layout;

People.js (inside components directory)

const React = require('react');

const People = React.createClass({
	render () {
		return (
			<div>
				<p>{'list of People'}</p>
				<ul>
					{this.props.people.map(people => <li key={people.id}>{people.name} is of age {people.age}</li>)}
				</ul>
			</div>
		);
	}
});

module.exports = People;

As you can see, by default I am prerendering the Layout component which is a parent of People. Layout component accepts two props which are:

  • predata: just a string, nothing special
  • people: which is a multidimensional array that would translate into an array of many objects in javascript.

where the props people is actually used for the People component and obviously I couldn't pre-render People component and pre-render Layout component as well because it would cause the People component to be processed twice, therefore, you'll see two People component in the document.

The good thing about having to pre-render data is that even if they have no javascript enabled the data would actually still be loaded in the DOM.

Now what if I would like to pre-render the data inside my redux store?

according to the Redux Docs about Server Side Rendering they actually loaded the pre-rendered data into the window.__preloadedstore__. Any other way that is supported by the framework as well?

aprilmintacpineda avatar Nov 23 '16 16:11 aprilmintacpineda