我开始为Rails应用程序使用ReactJS。
我很快注意到的一件事是在ReactJS组件中使用Ruby方法-通常,我每天使用的是格式化日期,缩短文本/字符串:
content = this.state.posts.map(post => {
return(
<li key={post.id}>
{post.created_at.strftime('%B')}
{post.message}
</li>
)
});
显然,这将引发错误
Uncaught TypeError: post.created_at.strftime is not a function
,因为我在javascript数据上应用了ruby方法(我曾经在Rails视图中执行过这些操作)。在/ ReactJS组件中,这里的正确方法是什么?我应该从控制器中的数据库中准备数据格式吗?还是应该研究JS函数来复制相应Ruby方法的行为?
还是有第三种方法可以做得更好?
最佳答案
有两个问题需要了解。
您上面的代码是JSX,它已翻译为javascript。除非您执行某些操作,否则浏览器上就没有Ruby(但请继续阅读)
第二个问题是,像post.id
和post.created_at
这样的实际方法都引用服务器上存在的数据,并且除非您进行某些操作以解决该问题,否则您将无法访问该数据。
如果要像上面一样编写代码,但是要在Ruby中运行,可以使用http://ruby-hyperloop.org。然后,您可以完全用Ruby编写上面的代码,它将起作用。
render do
state.posts.each do |post|
LI(key: post) do
"#{post.created_at.strftime('%B')} #{post.message}"
end
end
end
为了更深入地回答您的问题,这里是hyperloop的工作原理:首先,它使用Opal Ruby-> JS Transpiler和Rails链轮将红宝石代码转换为JS,然后再发送给客户端。这类似于ERB或Haml的工作方式。
其次,Hyperloop为您提供了完整的DSL,可使用Ruby(而不是JSX)编写React Component代码。
第三,Hyperloop使ActiveRecord模型在客户端和服务器之间保持同步。因此,当您在上述代码中执行
state.posts.each
时,这意味着您将需要从服务器中获取帖子,并且当它们到达时触发react组件的重新呈现。Hyperloop组件可以调用正常的React组件,同样,React组件也可以调用Hyperloop组件,因为在幕后所有东西都变成了标准的React.js组件。
顺便说一句,上面关于保持业务逻辑等分离的评论是正确的,并且在Hyperloop中使用与rails相同的机制得到了支持,但这是我认为的另一主题。