0

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?

1
  • My general rule is to keep data manipulations on the server side as much possible since it could easily evolve into more complicated business logic and since I just like working in ruby more than I do JS (bias here I know). Although, in that particular example, I would probably implement it on React side with a library (perhaps momentJS), with the reasoning of it being a formatting change and could be used again and again on the UI. Commented Feb 25, 2018 at 13:17

1 Answer 1

1

There are two issues to understand.

  1. 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)

  2. 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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.