This repository was archived by the owner on Oct 19, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathfeed.xml
More file actions
567 lines (490 loc) · 60.8 KB
/
feed.xml
File metadata and controls
567 lines (490 loc) · 60.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>React</title>
<description>Use Ruby to build Reactive User Interfaces</description>
<link>https://facebook.github.io/</link>
<atom:link href="https://facebook.github.io//feed.xml" rel="self" type="application/rss+xml" />
<item>
<title>Reactrb v0.8.5</title>
<description><p>Wow - its already been a hot sweaty summer around here in Reactrb land. First off after a lot of discussion and thinking we have decided to consistently rename everything <strong>Reactrb</strong>. We are sad to see the &quot;dot&quot; go, but this way the name is consistent everywhere, twitter handle, domain name, github org name, etc.</p>
<p>Within the <a href="https://github.com/reactrb">github org</a> we will use the reactb prefix for all gems and repos unless it really doesn&#39;t make sense. So you will find in the repo:</p>
<ul>
<li>reactrb-express (formerly inline-reactive-ruby)</li>
<li>reactrb-examples (looking help here to clean these up...)</li>
<li>reactrb-router (formerly reactive-router)</li>
<li>reactrb-rails-generator (formerly reactive<em>rails</em>generator)</li>
</ul>
<p>For the moment reactive-record is going to keep its name, just because its so much fun. There is a concept to make a gem called reactrb-model that would be the base for reactive-record, but would agnostic to the persistence mechanism.</p>
<p>This name change and reorganization should help make finding out about Reactrb easier, but its not going to help anybody write code faster or better. So we wanted to at least get in a few improvements as well:</p>
<ul>
<li><a href="#you-pick-your-react-version">You Pick Your React Version</a></li>
<li><a href="#better-native-imports">Better Native Imports</a></li>
<li><a href="#render-call-back">Render Call Back</a></li>
<li><a href="#caps-tag-names">CAPS Tag Names</a></li>
</ul>
<h2><a class="anchor" name="you-pick-your-react-version"></a>You Pick Your React Version <a class="hash-link" href="#you-pick-your-react-version">#</a></h2>
<p>We really needed this one... With every gem and javascript component bundle pulling for a different version of react, Reactrb needed to step out of the way!</p>
<p>Reactrb is now tested with React V13-V15, and by default does <em>not</em> include any version when you <code>require &#39;reactrb&#39;</code>. </p>
<p>This gives you at least three ways to include React source into your assets:</p>
<ol>
<li><p>If you are using Webpack or another Javascript dependency manager, then let the Javascript tool chain work out which version to use. </p>
<p>Just make sure that you include both <code>react</code> and <code>react-dom</code> as Reactrb needs both.</p></li>
<li><p>If you are using the react-rails gem then do a <code>require &#39;react&#39;</code> just before you do a <code>require &#39;reactrb&#39;</code> in your <code>components.rb</code> file. </p>
<p>This will load the version compatible with react-rails.</p></li>
<li><p>If you are using react-rails <em>and</em> a Javascript dependency manager, then check <a href="https://github.com/reactjs/react-rails/blob/master/VERSIONS.md">here</a> for the version that react-rails wants, and include that version explicitly with <code>npm</code> or whatever tool you are using on the JS side.</p>
<p>This will let the JS tool chain manage the dependencies, but insure you have a compatible version for react-rails.</p></li>
<li><p>Otherwise Reactrb includes (but does not require) several versions of react source. Just add <code>require &#39;react-latest&#39;</code> right above wherever you do a <code>require &#39;reactrb&#39;</code>. </p>
<p>If you want another version do <code>require &#39;react-v14&#39;</code> or <code>require &#39;react-v13&#39;</code></p></li>
</ol>
<h2><a class="anchor" name="better-native-imports"></a>Better Native Imports <a class="hash-link" href="#better-native-imports">#</a></h2>
<p>Previously you could not import single javascript components into the Reactrb namespace. They had to be wrapped is some kind of library structure for the <code>NativeLibrary</code> class to work. </p>
<p>We wanted to keep <code>NativeLibrary</code> as strictly the mechanism that imports libraries of components, and so we added the <code>imports</code> directive to <code>React::Component</code>.</p>
<p>So now you can say:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Griddle</span> <span class="o">&lt;&lt;</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span><span class="o">::</span><span class="no">Base</span>
<span class="n">imports</span> <span class="s1">'Griddle'</span>
<span class="k">end</span>
</code></pre></div>
<p>Now once you install the the <a href="http://griddlegriddle.github.io/Griddle/">Griddle</a> Javascript component you can use <code>Griddle</code> like any other Reactrb component.</p>
<p><em>But wait there&#39;s more...</em></p>
<p>Importing a ton of libraries this way could get tedious especially if you are using something like Webpack anyway to manage which components to include.</p>
<p>To keep things easy, you can opt in to <em>auto-import</em> by simply adding <code>require &#39;reactrb/auto-import&#39;</code> after you require reactrb.</p>
<p>With auto-importing enabled a component like <code>Griddle</code> or a library like <code>ReactBootstrap</code> will automatically be available to your Reactrb components.</p>
<p>See <a href="/using-javascript-components.html">Using Javascript Components</a> for more details.</p>
<h2><a class="anchor" name="render-call-back"></a>Render Call back <a class="hash-link" href="#render-call-back">#</a></h2>
<p>Up till now we have been defining the render method as just that <em>an instance method in your component class.</em> That&#39;s cool, and that still works, however for a couple of reasons we felt having a call back to define the render method would be handy. </p>
<ol>
<li><p><strong>Render methods are too large:</strong> Even using helper methods to keep things small, render methods often exceed the normal 10 line ruby style guide recommendation. </p>
<p>That is not a problem in itself - after all recommendations are just that. However if you are using tools like RuboCop, then it&#39;s sad when every single one of your components has a warning flag. You can turn off that cop of course, but then lose a very valuable check that most of the times should be followed. </p>
<p>By allowing render to be defined as a call back, you get rid of this problem.</p></li>
<li><p><strong>Get Rid of Boiler Plate:</strong> All components must have a single outer container, and for many components this container and its parameters are static. So the new render call back lets you specify the container component and its parameters as params to the callback. This eliminates two unnecessary lines per component, plus an unneeded level of indentation, and I think when used properly it makes things clearer.</p></li>
<li><p><strong>Consistency:</strong> All the other lifecycle methods are defined as callbacks, so its nice to have render fit in.</p></li>
</ol>
<p>Meanwhile the <code>Element[...].render</code> method which can be used to mount a top level component to a DOM element, has been updated to follow the same syntax as well. So for example to mount a component you can just say <code>Element[&#39;#top-level&#39;].render App</code>.</p>
<p>This is not a big deal but I think you should try it out, and see if it doesn&#39;t lead to more readable components.</p>
<h2><a class="anchor" name="caps-tag-names"></a>CAPS Tag Names <a class="hash-link" href="#caps-tag-names">#</a></h2>
<p>Its been suggested that especially for beginners its a little hard to parse the DSL. You don&#39;t know which method is what, and its hard to tell the difference between tags like <code>select</code> and other helper methods. One way to solve this is to write the built-in tag names in all caps, which the DSL now supports.</p>
<p>It was a small thing, so we went ahead and added it. Tell us what you think!</p>
</description>
<pubDate>2016-06-29T00:00:00-07:00</pubDate>
<link>https://facebook.github.io//blog/2016/06/29/reactrb-v0.8.5.html</link>
<guid isPermaLink="true">https://facebook.github.io//blog/2016/06/29/reactrb-v0.8.5.html</guid>
</item>
<item>
<title>Getting started with Rails</title>
<description><h1><a class="anchor" name="getting-started-with-react.rb-and-rails"></a>Getting started with react.rb and Rails <a class="hash-link" href="#getting-started-with-react.rb-and-rails">#</a></h1>
<p><a href="//facebook.github.io/react/">React.js</a> support for rails is provided
<a href="https://github.com/reactjs/react-rails">react-rails</a> gem.</p>
<p>From its project page, React-rails can:</p>
<ul>
<li> Provide various react builds to your asset bundle</li>
<li> Transform .jsx in the asset pipeline</li>
<li> Render components into views and mount them via view helper &amp; react_ujs</li>
<li> Render components server-side with prerender: true</li>
<li> Generate components with a Rails generator</li>
<li> Be extended with custom renderers, transformers and view helpers</li>
</ul>
<p>While <code>react-rails</code> provides easy integration with Rails, a Rails
developer cannot leverage the full benefits of React.js, particularly
isomorphic/<a href="https://medium.com/@mjackson/universal-javascript-4761051b7ae9#.rxrgqe5wb">universal</a>
domain logic code and views since different languages are used on
server and client
sides. <a href="https://github.com/zetachang/react.rb">React.rb/reactive-ruby</a>
(<strong>react.rb</strong> from here on) builds on top of <code>react-rails</code> by allowing
one to write React components in Ruby, courtesy of
<a href="http://opalrb.org">Opal</a>. Now the Rails programmer can also enjoy
universal domain logic and views written in Ruby via react.js.</p>
<p>The focus of this article will be limited to just getting <code>react.rb</code>
up and running on Rails from scratch.</p>
<h1><a class="anchor" name="generate-a-rails-project-that-uses-opal"></a>Generate a rails project that uses Opal <a class="hash-link" href="#generate-a-rails-project-that-uses-opal">#</a></h1>
<p>The easiest way to create a Rails project that uses <a href="http://opalrb.org">Opal</a> is to use the
<code>--javascript=opal</code> option. Manual instructions on how add Opal
support to an existing Rails project are given on the <a href="https://github.com/opal/opal-rails">opal-rails</a>
site. Create a new Rails project with the following command:</p>
<div class="highlight"><pre><code class="language-" data-lang="">% rails new getting-started-react-rails --javascript=opal
</code></pre></div><h1><a class="anchor" name="add-react.rb-gems-to-gemfile"></a>Add react.rb gems to Gemfile <a class="hash-link" href="#add-react.rb-gems-to-gemfile">#</a></h1>
<p>To use <code>react.rb</code>, you need to add 3 gems to your Gemfile:
reactive-ruby<sup><a id="fnr.1" class="footref" href="#fn.1">1</a></sup>, react-rails and therubyracer</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="n">gem</span> <span class="s1">'reactive-ruby'</span><span class="p">,</span> <span class="s1">'0.7.29'</span> <span class="c1"># nail down compatible version w/ pre 0.14 react-rails</span>
<span class="n">gem</span> <span class="s1">'react-rails'</span><span class="p">,</span> <span class="s1">'1.3.2'</span> <span class="c1"># react.rb not compatible ith 1.4.* yet so use this one</span>
<span class="n">gem</span> <span class="s1">'opal-rails'</span> <span class="c1"># already added w/the --javascript=opal option</span>
<span class="n">gem</span> <span class="s1">'therubyracer'</span><span class="p">,</span> <span class="ss">platforms: :ruby</span> <span class="c1"># Required for server side prerendering</span>
</code></pre></div>
<p>Run <code>bundle install</code> after these have been added to your Gemfile.</p>
<h3><a class="anchor" name="update"></a>Update <a class="hash-link" href="#update">#</a></h3>
<p>Since this article was written there has been Rails generator code
that has been written as a
<a href="https://rubygems.org/gems/reactrb-rails-generator">standalone gem</a>
that is pending integration with react.rb gem. Some of conventions
described in this article, which currently match that of existing
documentation and sample Rails project in react.rb will likely be
changing as part of that.</p>
<h1><a class="anchor" name="convert-application.js-to-application.js.rb"></a>Convert application.js to application.js.rb <a class="hash-link" href="#convert-application.js-to-application.js.rb">#</a></h1>
<p>When using opal-rails, it is recommented<sup><a id="fnr.2" class="footref" href="#fn.2">2</a></sup>
to convert the application.js file to application.js.rb. Make yours look
like this:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1"># app/assets/javascripts/application.js.rb</span>
<span class="nb">require</span> <span class="s1">'opal'</span>
<span class="nb">require</span> <span class="s1">'opal_ujs'</span>
<span class="nb">require</span> <span class="s1">'turbolinks'</span>
<span class="nb">require</span> <span class="s1">'react'</span>
<span class="nb">require</span> <span class="s1">'react_ujs'</span>
<span class="nb">require</span> <span class="s1">'components'</span> <span class="c1"># to include isomorphic react components on the client</span>
<span class="n">require_tree</span> <span class="s1">'.'</span>
</code></pre></div><h1><a class="anchor" name="setup-for-isomorphic3-react-components"></a>Setup for isomorphic<sup><a id="fnr.3" class="footref" href="#fn.3">3</a></sup> React components <a class="hash-link" href="#setup-for-isomorphic3-react-components">#</a></h1>
<p>A big perk of react.js is isomorphic code (same code on server and
client side), which leads to A united UI layer. As mentioned before
<a href="https://github.com/reactjs/react-rails">react-rails</a> provides server rendered react.js components, as well as
other perks as detailed in this <a href="http://bensmithett.com/server-rendered-react-components-in-rails/">this article</a>. This quote from the
aforementioned article gives one a sense of how big a perk this is.</p>
<blockquote>
<p>The Holy Grail. The united UI layer. Serve up real HTML on first page load, then kick off a client side JS app. All without duplicating a single line of UI code.</p>
</blockquote>
<p>Those who have struggled with duplicated views on front and back ends,
in different languages should appreciate that sentiment. To support
isomorphic react.rb components you need to setup a structure for these
<strong>shared</strong> components. The current convention is to make a
<code>app/views/components</code> directory containing the components and a
<code>components.rb</code> manifest file that will require all the <code>react.rb</code>
components, like so:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1"># app/views/components.rb</span>
<span class="nb">require</span> <span class="s1">'opal'</span>
<span class="nb">require</span> <span class="s1">'reactive-ruby'</span>
<span class="n">require_tree</span> <span class="s1">'./components'</span>
</code></pre></div>
<p>You may have noticed that, that the <code>application.js.rb</code> we created
<code>require</code>s this components.rb file to compile these universal
<code>react.rb</code> components.</p>
<h1><a class="anchor" name="make-a-controller-to-demonstrate-react-components"></a>Make a controller to demonstrate react components <a class="hash-link" href="#make-a-controller-to-demonstrate-react-components">#</a></h1>
<p>We will be demonstrating several types of components as
examples. Let&#39;s make a dedicated controller to demo these components with
dedicated actions for each case.</p>
<div class="highlight"><pre><code class="language-sh" data-lang="sh"> % rails g controller home isomorphic iso_convention search_path client_only
</code></pre></div><h1><a class="anchor" name="create-your-first-react-component"></a>Create your first React Component <a class="hash-link" href="#create-your-first-react-component">#</a></h1>
<p>So now that we&#39;re setup for isomorphic components, lets make our first
react.rb component. We&#39;ll start with a simple &quot;Hello World&quot;
component. This component takes a single, required param message of
type <code>String</code>. Note, param in <code>react.rb</code> corresonds to prop in
react.js; <code>react.rb</code> calls props &quot;params&quot; to provide a more Rails
familiar API. The component renders this message param in an <strong>h1</strong> element,
and renders a button that, when clicked, calls <code>alert()</code> with the same
message.</p>
<p>Put the following into this file <strong>app/views/components/hello.rb</strong>:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">Hello</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="n">required_param</span> <span class="ss">:what</span><span class="p">,</span> <span class="ss">type: </span><span class="no">String</span>
<span class="k">def</span> <span class="nf">message</span>
<span class="s2">"Hello </span><span class="si">#{</span><span class="n">what</span><span class="si">}</span><span class="s2">"</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">div</span> <span class="p">{</span>
<span class="n">h1</span> <span class="p">{</span> <span class="n">message</span> <span class="p">}</span>
<span class="n">button</span> <span class="p">{</span><span class="s2">"Press me"</span><span class="p">}.</span><span class="nf">on</span><span class="p">(</span><span class="ss">:click</span><span class="p">)</span> <span class="p">{</span><span class="n">alert</span> <span class="n">message</span><span class="p">}</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>You can render the <code>Hello</code> component directly without needing a
template file in your controller with
<code>render_component()</code>. <code>render_component()</code> takes an optional (more on
this later) class name of the component and any parameters you wish to
pass the component. Implement the <code>isomorphic</code> action in the
<code>HomeController</code> like so</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">HomeController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">isomorphic</span>
<span class="n">render_component</span> <span class="s1">'Hello'</span><span class="p">,</span> <span class="ss">message: </span><span class="s1">'World'</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Start the server, then visit <a href="http://localhost:3000/home/isomorphic"><a href="http://localhost:3000/home/isomorphic">http://localhost:3000/home/isomorphic</a></a> to
view the component. By default, react.rb prerenders the component on
the server (the reverse of react-rails&#39; <code>react_component()</code>, but you can force Rails to NOT prerender by appending
?no_prerender=1 to the url, like so</p>
<div class="highlight"><pre><code class="language-" data-lang="">http://localhost:3000/home/isomorphic?no_prerender=1
</code></pre></div>
<p>Let&#39;s take a quick look at the HTML returned by the server in both cases (formatted to be more human-readable)</p>
<p>For <a href="http://localhost:3000/home/isomorphic"><a href="http://localhost:3000/home/isomorphic">http://localhost:3000/home/isomorphic</a></a>
we see the <strong>h1</strong> and button rendered from the server:</p>
<div class="highlight"><pre><code class="language-html" data-lang="html"> <span class="nt">&lt;div</span> <span class="na">data-react-class=</span><span class="s">"React.TopLevelRailsComponent"</span>
<span class="na">data-react-props=</span><span class="s">"{&amp;quot;render_params&amp;quot;:{&amp;quot;message&amp;quot;:&amp;quot;World&amp;quot;},&amp;quot;component_name&amp;quot;:&amp;quot;Hello&amp;quot;,&amp;quot;controller&amp;quot;:&amp;quot;Home&amp;quot;}"</span><span class="nt">&gt;</span>
<span class="nt">&lt;div</span> <span class="na">data-reactid=</span><span class="s">".3hx9dqn6rk"</span>
<span class="na">data-react-checksum=</span><span class="s">"487927662"</span><span class="nt">&gt;</span>
<span class="nt">&lt;h1</span> <span class="na">data-reactid=</span><span class="s">".3hx9dqn6rk.0"</span><span class="nt">&gt;</span>Hello World<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;button</span> <span class="na">data-reactid=</span><span class="s">".3hx9dqn6rk.1"</span><span class="nt">&gt;</span>Press me<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div>
<p>For <a href="http://localhost:3000/home/isomorphic?no_prerender=1"><a href="http://localhost:3000/home/isomorphic?no_prerender=1">http://localhost:3000/home/isomorphic?no_prerender=1</a></a>
there is no prerendering and the rendering is done by the client</p>
<div class="highlight"><pre><code class="language-html" data-lang="html"> <span class="nt">&lt;div</span> <span class="na">data-react-class=</span><span class="s">"React.TopLevelRailsComponent"</span>
<span class="na">data-react-props=</span><span class="s">"{&amp;quot;render_params&amp;quot;:{&amp;quot;message&amp;quot;:&amp;quot;World&amp;quot;},&amp;quot;component_name&amp;quot;:&amp;quot;Hello&amp;quot;,&amp;quot;controller&amp;quot;:&amp;quot;Home&amp;quot;}"</span><span class="nt">&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div><h1><a class="anchor" name="rails-conventions-isomorphic-i.e.-universal-components-and-the-default-component"></a>Rails conventions, isomorphic (i.e. universal) components and the &quot;default&quot; component <a class="hash-link" href="#rails-conventions-isomorphic-i.e.-universal-components-and-the-default-component">#</a></h1>
<p>In the Rails tradition of convention over configuration, you can
structure/name your components to match your controllers to support a
&quot;default&quot; component, i.e. a component you do NOT need to specify, for
a controller action. To make a default component for the
<code>HomeController#iso_convention</code> action, create the following file:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1"># app/views/components/home/iso_convention.rb</span>
<span class="k">module</span> <span class="nn">Components</span>
<span class="k">module</span> <span class="nn">Home</span>
<span class="k">class</span> <span class="nc">IsoConvention</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h1</span> <span class="p">{</span> <span class="s2">"the message is: </span><span class="si">#{</span><span class="n">params</span><span class="p">[</span><span class="ss">:message</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>We now call <code>render_component()</code> in the action, passing only the
desired params in the action. <code>render_component()</code> will instantiate
the <strong>default</strong> component.</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">HomeController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">iso_convention</span>
<span class="n">render_component</span> <span class="ss">message: </span><span class="s1">'World'</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Browsing <a href="http://localhost:3000/home/iso_convention"><a href="http://localhost:3000/home/iso_convention">http://localhost:3000/home/iso_convention</a></a>
will render the <code>Components::Home::IsoConvention</code> component</p>
<h1><a class="anchor" name="the-component-search-path"></a>The component search path <a class="hash-link" href="#the-component-search-path">#</a></h1>
<p>For consistency, you should stick with the Rails directory and
filename conventions. There is some flexibility in where you can
place components. The search path for isomorphic components in
react.rb is described here: <a href="https://github.com/zetachang/react.rb#changing-the-top-level-component-name-and-search-path">here</a> which writes:</p>
<blockquote>
<p>Changing the top level component name and search path</p>
<p>You can control the top level component name and search path.</p>
<p>You can specify the component name explicitly in the
render_component method. render_component &quot;Blatz will search the
for a component class named Blatz regardless of the controller
method.</p>
<p>Searching for components normally works like this: Given a
controller named &quot;Foo&quot; then the component should be either in the
Components::Foo module, the Components module (no controller -
useful if you have just a couple of shared components) or just the
outer scope (i.e. Module) which is useful for small apps.</p>
<p>Saying render_component &quot;::Blatz&quot; will only search the outer scope,
while &quot;::Foo::Blatz&quot; will look only in the module Foo for a class
named Blatz.</p>
</blockquote>
<h1><a class="anchor" name="exploring-the-component-search-path"></a>Exploring the component search path <a class="hash-link" href="#exploring-the-component-search-path">#</a></h1>
<p>Let&#39;s play around with several components that have the same class name and
see how the search path resolves which component to use. Create the
file below:</p>
<p><code>app/views/components/search_path.rb</code></p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1"># This class departs from 1 class/file and diretory</span>
<span class="c1"># structure/convention, using this to test search path</span>
<span class="k">class</span> <span class="nc">SearchPath</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h1</span> <span class="p">{</span><span class="s2">"::SearchPath"</span><span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Home</span>
<span class="k">class</span> <span class="nc">SearchPath</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h1</span> <span class="p">{</span><span class="s2">"Home::SearchPath"</span><span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Components</span>
<span class="k">class</span> <span class="nc">SearchPath</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h2</span> <span class="p">{</span> <span class="s1">'Components::SearchPath'</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Components</span>
<span class="k">module</span> <span class="nn">Home</span>
<span class="k">class</span> <span class="nc">SearchPath</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h2</span> <span class="p">{</span> <span class="s1">'Components::Home::SearchPath'</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>To render the &quot;default&quot; component, we can just call <code>render_component()</code>:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">HomeController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">search_path</span>
<span class="n">render_component</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Hitting <a href="http://localhost:3000/home/search_path"><a href="http://localhost:3000/home/search_path">http://localhost:3000/home/search_path</a></a> the component rendered
<code>Home::SearchPath</code> as evidenced by the text in the H1 element.</p>
<p>Specifying the component by unqualified class name in <code>render_component()</code>, yields the same result: <code>Home::SearchPath=</code></p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">HomeController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">search_path</span>
<span class="n">render_component</span> <span class="s2">"SearchPath"</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>We can explore what will be found next the search path by changing the
found component&#39;s name to <code>SearchPath1</code>, and then refreshing
<a href="http://localhost:3000/home/search_path">http://localhost:3000/home/search_path</a> to see which component is
found. Doing this for each found component gets the following
results:</p>
<table style='border:2px black; borderspacing: 4px; ' cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
</colgroup>
<thead>
<tr style='border:2px solid black; padding: 4px; '>
<th style='border:2px solid black; padding: 4px; 'scope="col" class="org-left">Class name changed from SearchPath</th>
<th style='border:2px solid black; padding: 4px; 'scope="col" class="org-left">Component Rendered by search path</th>
</tr>
</thead>
<tbody>
<tr style='border:2px solid black; padding: 4px; '>
<td style='border:2px solid black; padding: 4px; 'class="org-left">none</td>
<td style='border:2px solid black; padding: 4px; 'class="org-left">Home::SearchPath</td>
</tr>
<tr style='border:2px solid black; padding: 4px; '>
<td style='border:2px solid black; padding: 4px; 'class="org-left">Home::SearchPath</td>
<td style='border:2px solid black; padding: 4px; 'class="org-left">Components::Home::SearchPath</td>
</tr>
<tr style='border:2px solid black; padding: 4px; '>
<td style='border:2px solid black; padding: 4px; 'class="org-left">Components::Home::SearchPath</td>
<td style='border:2px solid black; padding: 4px; 'class="org-left">::SearchPath</td>
</tr>
<tr style='border:2px solid black; padding: 4px; '>
<td style='border:2px solid black; padding: 4px; 'class="org-left">::SearchPath</td>
<td style='border:2px solid black; padding: 4px; 'class="org-left">Components::SearchPath</td>
</tr>
</tbody>
</table>
<p>If we rename all the <code>SearchPath1</code> classes back to <code>SearchPath</code>, we
can force the search path to find our desired component by specifying
the full namespace in the <code>render_component()</code> call</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="k">class</span> <span class="nc">HomeController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">search_path</span>
<span class="n">render_component</span> <span class="s2">"SearchPath"</span>
<span class="c1"># render_component "Components::SearchPath"</span>
<span class="c1"># render_component "Components::Home::SearchPath"</span>
<span class="c1"># render_component "Home::SearchPath"</span>
<span class="c1"># render_component "::SearchPath"</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div><h1><a class="anchor" name="directory-conventions-for-react-rails-opal-and-react.rb"></a>Directory conventions for react-rails, Opal and react.rb <a class="hash-link" href="#directory-conventions-for-react-rails-opal-and-react.rb">#</a></h1>
<p>The <strong>react-rails</strong> Javascript component generators create react.js
components in the <code>app/assets/javascripts/components</code> directory. This
makes sense, esp. since Rails out of the box does NOT support
isomorphic code and views; hence this directoy is a logical and
&quot;Rails-like&quot; place for Javascript to go. Similarly, if you are just
using opal-rails and not not react.rb, then by convention, your <code>Opal</code>
code will be placed under <code>app/assets/javascripts</code> where the asset
pipeline knows how to find and transpile the <code>Opal</code> files to Javascript.
React.rb challenges these directory conventions. As react.js is often
called the <strong>V</strong> of <strong>MVC</strong>, then it makes sense for react.rb components
to live under the <code>app/views/components</code> directory, esp. as they can
also be rendered on the server. React.rb is young, and conventions
may change, but at the momemnt this is the prescribed convention.</p>
<p>You can create react.rb components more in line with react-rails and
Opal conventions by placing them somewhere under the
<code>app/assets/javascripts</code> directory. The Opal files will be found by
Rails anywhere that the asset pipeline is configured to find
javascript files for both server and client rendering, but I would
recommend a structure similar to how react-rails, i.e. in
<code>app/assets/javascripts/components</code> to make them easy to find.</p>
<p>Let&#39;s put the &quot;client side only&quot; component into
<code>app/assets/javascripts</code>. Since Opal will find the file anywhere the
asset pipeline knows to look, this would be more for organizational
conventions rather than a configuration necessary to make it work.</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"> <span class="c1"># app/assets/javascripts/components/client_only.rb</span>
<span class="k">class</span> <span class="nc">ClientOnly</span>
<span class="kp">include</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span>
<span class="n">required_param</span> <span class="ss">:message</span><span class="p">,</span> <span class="ss">type: </span><span class="no">String</span>
<span class="k">def</span> <span class="nf">render</span>
<span class="n">h1</span> <span class="p">{</span> <span class="s2">"Client only: </span><span class="si">#{</span><span class="n">params</span><span class="p">[</span><span class="ss">:message</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div>
<p>Then in the template for the <code>client_only</code> action , you can render the
component client side via the <code>react_component()</code> view helper provided
by react-rails. Since react.rb wraps calls to react.js, the components
become react.js components.</p>
<div class="highlight"><pre><code class="language-html" data-lang="html"> <span class="nt">&lt;h1&gt;</span>Home#client_only<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;p&gt;</span>Find me in app/views/home/client_only.html.erb<span class="nt">&lt;/p&gt;</span>
<span class="err">&lt;</span>%= react_component 'ClientOnly', message: 'World' %&gt;
</code></pre></div><h1><a class="anchor" name="thats-all-for-now."></a>That&#39;s all for now. <a class="hash-link" href="#thats-all-for-now.">#</a></h1>
<p>So now you have a Rails project with react.rb running with several
examples of react.rb components. All of this code exists in a rails
project
<a href="https://github.com/fkchang/getting-started-react-rails">here.</a> This
should be enough to get one started. Enjoy react.rb and Rails!</p>
<h2 class="footnotes">Footnotes: </h2>
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara">reactive-ruby will fold back into react.rb with the 0.9.0 versions (currently at 0.7.36). Plans are discussed in the react.rb [roadmap](https://github.com/zetachang/react.rb#road-map)</div></div>
<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup>
<div class="footpara">A change was made starting with Opal 0.8.\*, to support ordered
requires. If one wishes to continue to use application.js instead
application.rb, one needs to manually load each opal file in the
application.js, as below. Use of application.rb will automatically load the files in question
</div></div>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="c1">// application.js</span>
<span class="c1">//= require opal</span>
<span class="c1">//= require greeter</span>
<span class="c1">//= require_self</span>
<span class="nx">Opal</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">'greeter'</span><span class="p">);</span> <span class="c1">// you have to load the opal file</span>
<span class="c1">// etc.</span>
</code></pre></div>
<div class="footdef"><sup><a id="fn.3" class="footnum" href="#fnr.3">3</a></sup> <div class="footpara">While the pattern is that universal will be taking the place of isomorphic, I will use the term isomorphic here because the react.rb docs refer to it as isomorphic</div></div>
</description>
<pubDate>2016-01-26T00:00:00-08:00</pubDate>
<link>https://facebook.github.io//blog/2016/01/26/getting-started-with-rails.html</link>
<guid isPermaLink="true">https://facebook.github.io//blog/2016/01/26/getting-started-with-rails.html</guid>
</item>
<item>
<title>Reactive-Ruby v0.7.32</title>
<description><p>As we march towards the next official release of react.rb, we wanted to make some syntactic improvements to the component macros and methods. The overall
intent is to make react.rb more <em>ruby</em> like, and reduce syntactic noise, while maintaining ties to react.js.</p>
<p>While we are very close to being ready to make an official react.rb release we are still maintaining these changes as the master branch of react.rb, and distributing the changes via the reactive-ruby gem. </p>
<p>Here is a summary of the changes in v0.7.32</p>
<ul>
<li><h4><a class="anchor" name="inheriting-from-reactcomponentbase"></a>Inheriting from <code>React::Component::Base</code> <a class="hash-link" href="#inheriting-from-reactcomponentbase">#</a></h4>
<p>You can now define components by inheriting from <code>React::Component::Base</code>.</p>
<p>For example:</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Widget</span> <span class="o">&lt;</span> <span class="no">React</span><span class="o">::</span><span class="no">Component</span><span class="o">::</span><span class="no">Base</span>
<span class="c1"># etc</span>
<span class="k">end</span>
</code></pre></div>
<p>Note you can still use <code>include React::Component</code> to define components as well.</p>
<p>As part of this change you can also subclass any component. Any lifecycle macros in child classes will execute before the parent class.</p></li>
<li><h4><a class="anchor" name="state-and-params-component-methods"></a><code>state</code> and <code>params</code> component methods <a class="hash-link" href="#state-and-params-component-methods">#</a></h4>
<p>To access state variables and params you must now prefix with the <code>state</code>and <code>param</code> methods.</p>
<p>While adding some typing it solves two problems: First it avoids shadowing dsl methods such as <code>label</code>, and secondly it makes the code more readable.</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">state</span><span class="p">.</span><span class="nf">items</span> <span class="c1"># items without the state prefix is deprecated</span>
<span class="n">state</span><span class="p">.</span><span class="nf">items!</span> <span class="c1"># likewise for updating state</span>
<span class="n">params</span><span class="p">.</span><span class="nf">user</span> <span class="c1"># user without the params prefix is deprecated</span>
</code></pre></div></li>
<li><h4><a class="anchor" name="simplified-param-declarations"></a>Simplified Param Declarations <a class="hash-link" href="#simplified-param-declarations">#</a></h4>
<p>Instead of <code>optional_param</code>, and <code>required_param</code>, both macros have been replaced by <code>param</code>.</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">param</span> <span class="ss">:foo</span> <span class="c1"># instead of required_param :foo</span>
<span class="n">param</span> <span class="ss">bar: </span><span class="mi">12</span> <span class="c1"># instead of optional_param :foo, default: 12</span>
<span class="n">param</span> <span class="ss">:bar</span> <span class="ss">default: </span><span class="mi">12</span> <span class="c1"># slightly longer but more explicit</span>
<span class="n">param</span> <span class="ss">:foo</span><span class="p">,</span> <span class="ss">type: </span><span class="no">Hash</span> <span class="c1"># type spec works the same</span>
</code></pre></div>
<p>Both <code>optional_param</code> and <code>required_param</code> (and the plural aliases) are deprecated.</p></li>
<li><h4><a class="anchor" name="implicit-state-variable-creation"></a>Implicit State Variable Creation <a class="hash-link" href="#implicit-state-variable-creation">#</a></h4>
<p>When you reference a state variable (via the <code>state</code> method described above) the state will be automatically created. </p>
<p>The rationale is to make state variables more like instance variables. And like instance variables, good style would ask that all state variables be initialized in the <code>before_mount</code> callback. At this time it has not been determined if define_state will be deprecated, but you are strongly encouraged not to use it, or provide feedback.</p></li>
<li><h4><a class="anchor" name="simplified-component-mounting-with-jquery"></a>Simplified Component Mounting with JQuery <a class="hash-link" href="#simplified-component-mounting-with-jquery">#</a></h4>
<p>The jQuery wrapper class <code>Element</code> now has a <code>render</code> method.</p>
<div class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="no">Element</span><span class="p">[</span><span class="s1">'#container'</span><span class="p">].</span><span class="nf">render</span> <span class="p">{</span> <span class="n">div</span> <span class="p">{</span> <span class="s2">"hello"</span> <span class="p">}</span> <span class="p">}</span>
</code></pre></div>
<p>The <code>render</code> method takes a block, and mounts the react element generated by the block into the first dom element in the jQuery result.</p>
<p>React does not depend on opal-jquery and so opal-jquery must be required before the reactive-ruby gem, for the <code>render</code> method to be added to the <code>Element</code> class.</p></li>
</ul>
</description>
<pubDate>2015-12-01T00:00:00-08:00</pubDate>
<link>https://facebook.github.io//blog/2015/12/01/reactive-ruby-v0.7.32.html</link>
<guid isPermaLink="true">https://facebook.github.io//blog/2015/12/01/reactive-ruby-v0.7.32.html</guid>
</item>
</channel>
</rss>