Notes
Blocks in Ruby
Ruby methods may receive a block which is simply an anonymous function.
The following code in Ruby:
is roughly equivilent to this Javascript
In Ruby blocks may be specified either using do ... end
or with { ... }
:
Standard style reserves the { ... }
notation for single line blocks, and do ... end
for multiple line blocks.
Component Instances
Currently when generating a component the actual value returned after processing by React is an instance of class Element
. The long term plan is to merge these two concepts back together so that Element instances and Component instances will be the same. The major difference at the moment is that an Element carries all the data needed to create a Component Instance, but has not yet been rendered. Through out this document we will use element and component instance interchangeably.
Ruby Hash Params
In Ruby if the final argument to a method is a hash you may leave the {...}
off:
The HyperComponent Base Class
By convention all your components inherit from the HyperComponent
base class, which would typically look like this:
The Hyperstack Rails installer and generators will create this class for you if it does not exist, or you may copy the above to your
components
directory.
Having an application wide HyperComponent
class allows you to modify component behavior on an application basis, similar to the way Rails uses ApplicationRecord
and ApplicationController
classes.
This is just a convention. Any class that includes the
Hyperstack::Component
module can be used as a Component. You also do not have to name itHyperComponent
. For example some teams preferApplicationComponent
more closely following the Rails convention. If you use a different name for this class be sure to set theHyperstack.component_base_class
setting so the Rails generators will use the proper name when generating your components. more details...
Abstract and Concrete Components
An abstract component class is intended to be the base class of other components, and thus does not have a render block. A class that defines a render block is a concrete class. The distinction between abstract and concrete is useful to distinguish classes like HyperComponent
that are intended to be subclassed.
Abstract classes are often used to share common code between subclasses.
Word Count Method
Ownership
In the Avatar example instances of Avatar
own instances of ProfilePic
and ProfileLink
. In Hyperstack (like React), an owner is the component that sets the params
of other components. More formally, if a component X
is created in component Y
's render
method, it is said that X
is owned by Y
. As will be discussed later a component cannot mutate its params
— they are always consistent with what its owner sets them to. This fundamental invariant leads to UIs that are guaranteed to be consistent.
It's important to draw a distinction between the owner-owned-by relationship and the parent-child relationship. The owner-owned-by relationship is specific to Hyperstack/React, while the parent-child relationship is simply the one you know and love from the DOM. In the example above, Avatar
owns the DIV
, ProfilePic
and ProfileLink
instances, and DIV
is the parent (but not owner) of the ProfilePic
and ProfileLink
instances.
Generating Keys
Every Hyperstack object whether its a string, integer, or some complex class responds to the to_key
method. When you provide a component's key parameter with any object, the object's to_key
method will be called, and return a unique key appropriate to that object.
For example strings, and numbers return themselves. Other complex objects return the internal object_id
, and some classes provide their own to_key
method that returns some invariant value for each instance of that class. HyperModel records return the database id for example.
If you are creating your own data classes keep this in mind. You simply define a to_key
method on the class that returns some value that will be unique to that instance. And don't worry if you don't define a method, it will default to the one provided by Hyperstack.
Proper Use Of Keys
For best results the key
is supplied at highest level possible.
NOTE THIS MAY NO LONGER BE AN ISSUE IN LATEST REACT)
Ruby Procs
A core class of objects in Ruby is the Proc. A Proc (Procedure) is an object that can be called.
Ruby has several ways to create procs:
And there are several more ways, each with its differences and uses. You can find lots of details on Procs by searching online. Here is a good article to get you started...
The most common ways you will use Procs in your Hyperstack code is to define either lifecycle or component callbacks:
The different ways of specifying callbacks allow you to keep your code clear and consise, but in the end they do the same thing.
Note that there are subtle differences between Proc.new and lambda, that are beyond the scope of this note.
Javascript
Opal-Ruby uses the backticks and %x{ ... }
to drop blocks of Javascript code directly into your Ruby code.
Both the backticks and %x{ ... }
work the same, but the %{ ... }
notation is useful for multiple lines of code.
How Importing Works
Hyperstack automates as much of the process as possible for bridging between React and Javascript, however you do have lower level control as needed.
Let's say you have an existing React Component written in Javascript that you would like to access from Hyperstack.
Here is a simple hello world component:
I'm sorry I can't resist. Really?
In what world is the Ruby not much better than that JS hot mess.
Assuming that this component is loaded some place in your assets, you can then access this from Hyperstack by creating a wrapper Component:
The imports
directive takes a string (or a symbol) and will simply evaluate it and check to make sure that the value looks like a React component, and then set the underlying native component to point to the imported component.
Normally you do not have to use imports
explicitly. When Hyperstack finds a component named in your code that is undefined it searches for a Javascript class whose matches, and which acts like a React component class. Once find it creates the class and imports for you.
You may also turn off the autoimport function if necessary in your hyperstack.rb
initializer:
The Enter Event
The :enter event is short for catching :key_down and then checking for a key code of 13.
Last updated