Reputation: 48443
I am starting playing with ReactJS for my Rails apps.
One of the things I noticed very soon would be using Ruby methods in ReactJS components - typically, what I am using daily, is formatting date, shortening text/strings:
content = this.state.posts.map(post => {
return(
<li key={post.id}>
{post.created_at.strftime('%B')}
{post.message}
</li>
)
});
This will obviously raise an error Uncaught TypeError: post.created_at.strftime is not a function
, because I am applying a ruby method on javascript data (I am used to do these operations in Rails views).
What's the correct approach here with /in ReactJS components? Should I pre-prepare the format of data from database in the controller? Or should I research for JS functions to replicate the behavior of the respective Ruby methods?
Or is there a third way to do this a better way?
Upvotes: 0
Views: 1025
Reputation: 2878
There are two issues to understand.
The code you have above is JSX which is translated into javascript. Unless you do something you don't have Ruby on the browser (but read on)
The second is that the actual methods like post.id
and post.created_at
are referring to data that exists on the server, and again unless you do something to fix this you don't have access to that data.
If you want to write code like you have above, but in Ruby and have it work, you can use http://ruby-hyperloop.org . You can then write the above code entirely in Ruby and it will work.
render do
state.posts.each do |post|
LI(key: post) do
"#{post.created_at.strftime('%B')} #{post.message}"
end
end
end
To more deeply answer your question here is how hyperloop works: First it uses the Opal Ruby->JS transpiler and Rails sprockets to translate your ruby code to JS before sending it the client. This is similar to how ERB or Haml works.
Secondly Hyperloop gives you a complete DSL that lets write your React Component code in Ruby instead of JSX.
Thirdly Hyperloop keeps ActiveRecord models synchronized between the client and server. So when in the above code you do a state.posts.each
this means you are will need to fetch the posts from the server, and when they arrive trigger a rerender of the react component.
Hyperloop components can call normal react components, and likewise react components can call hyperloop components, since under the hood everything becomes a standard React.js component.
BTW the comment above about keeping business logic, etc separate is correct, and is supported in Hyperloop using the same mechanisms as rails, but that is another topic I think.
Upvotes: 1