我是第一次在 Rails 应用程序中工作,我正在尝试将前端转换为 React。我正在做这个逐个 View ,现在我正在处理菜单栏,它有基于用户是否登录的链接。请参阅下面的原始 Rails erb 代码:
<ul class="nav-right-links">
<% if user_signed_in? %>
<li><%= link_to 'Account', edit_user_registration_path %></li>
<li><%= link_to 'Sign out', destroy_user_session_path, :method=>'delete' %></li>
<% else %>
<li><%= link_to 'Sign in', new_user_session_path %></li>
<li><%= link_to 'Sign up', new_user_registration_path %></li>
<% end %>
<li><a href="/connections/help">Help</a></li>
</ul>
我发现此身份验证是由名为 Devise 的 Rails Gem 完成的。我想通过设计来保持身份验证,但我只需要弄清楚如何将一些逻辑放入 React 中。如果你很好奇,这里是我到目前为止的一些 react 代码。现在我只是在使用 hrefs,但显然它没有响应用户是否登录:
render () {
return (
<div style={styles.container}>
<ul style={styles.leftNav}>
{leftLinks.map(link => {
return (
<li style={styles.listElement}><a style={styles.link} href={link.path}> {link.name} </a> </li>
);
})}
</ul>
</div>
);
}
非常感谢任何帮助!
最佳答案
我们想要的是一个组件(我们称之为 LoginMenu)来替换这个 ERB 部分。
让我们通过弄清楚我们将如何摆脱特定的 ERB 代码来分解它,其中有以下结构:
-
<% if user_signed_in? %> ... <% else %> ... <% end %>
-
<%= link_to 'Account', edit_user_registration_path %>
-
<%= link_to 'Sign out', destroy_user_session_path, :method=>'delete' %>
-
<%= link_to 'Sign in', new_user_session_path %>
-
<%= link_to 'Sign up', new_user_registration_path %>
1、2 和 3 都需要一个 user_id(可能为 nil)。如果存在非零 user_id,则“用户已登录”,用户的 ID 可用于构建编辑和销毁路径。其他两条路径(4、5)为常数值。
因此,您的组件需要的是作为 prop 发送的 user_id。然后你可以这样说
if (props["user_id"]) {
... build and render the edit and destroy links using the value of props["user_id"]
} else {
... build the signin, and signup links
}
你可以像这样制作一些辅助函数:
edit_user_link: function {
<a style=... href={"/user/"+props["user_id"]+/edit"} >
}
等...
假设你正在使用 react-rails 那么你将拥有
<%= react_component "LoginMenu", user_id: @user ? @user.id : nil %>
此时页面的大部分内容都不是“响应式(Reactive)”的,但根据我们的经验,登录是最难使用react式的事情之一,所以暂时保持原样。
仅供引用...如果您刚刚起步,您可能需要考虑 http://reactrb.org这将使您可以使用 ruby 编写客户端代码,因此您不会尝试同时学习三种不同的语言(ruby、js、JSX)。
例如,您的 ruby 组件看起来像这样(这实际上会在 Stack Overflow 中运行...)
<script type="text/ruby">
# the above script tag just allows us to run in SO
# In your app User would be your user model, we are just going to stub it here
class User # < ActiveRecord::Base - just stub user for now
def id
12
end
end
# Here is your component. Normally this would be in the file
# app/views/components/login.rb by convention
class LoginMenu < React::Component::Base
param :user, type: User
def render
ul.nav_right_links do
if params.user #react.rb refers to props as params
li { a(href: "/user/#{params.user.id}/edit") { "Account" } }
li { a(href: "/user/#{params.user.id}/delete") { "Delete" } }
else
li { a(href: "/user/new") { "Sign Up" } }
li { a(href: "/user/login") { "Sign In" } }
end
li { a(href: "/connections/help") { "Help" } }
end
end
end
# the following just fires up our component in stack overflow...
# in your app you would do this in the controller:
# <%= react_component "LoginMenu", user: @user %>
Element['#container'].render { LoginMenu(user: User.new) }
</script>
<div id="container"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/reactive-ruby/inline-reactive-ruby/master/inline-reactive-ruby.js"></script>
此外http://reactrb.org其中有一个很好的基础教程,您可以查看这些幻灯片了解哪些涵盖了 rails 集成细节:http://slides.com/mitchvanduyn/deck-1
关于通过 Ruby Gem Devise 进行 JavaScript React 身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35462718/