You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails+React项目中结合ERB实现React组件内用户登录状态判断

解决方案

你可以通过两种成熟的方案实现React组件内的登录状态校验,两种方案都可以适配你当前的技术栈:

方案1:复用现有GraphQL查询逻辑(推荐)

你当前的QUERY语句已经包含了viewer字段的查询,绝大多数Rails+GraphQL的鉴权逻辑会默认返回:

  • 已登录状态:viewer为当前用户对象,包含id等字段
  • 未登录状态:viewer为null

实现步骤:

  1. 组件内先通过viewer字段判断登录状态
  2. 点赞按钮点击时优先校验登录状态,未登录直接跳转到登录页
  3. 补充说明:你当前的upVote仅修改了本地数据,未同步到后端,实际使用时需要补全GraphQL突变调用逻辑
    修改后的完整组件代码:
import * as React from 'react';
import gql from 'graphql-tag';
import { useQuery } from 'react-apollo';
import renderComponent from './utils/renderComponent';

const QUERY = gql`
  query PostsPage {
    viewer {
      id
    }
    ReviewsAll {
      id
      title
      tagline
      url
      commentsCount
      votes
    }
  }
`;

// 你后续可以替换为真实的GraphQL突变调用
function upVote(review) {
  review.votes += 1;
}

function ReviewsIndex() {
  const { data, loading, error } = useQuery(QUERY);
  
  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  // 新增:通过viewer判断登录状态
  const isLoggedIn = !!data?.viewer?.id;
  // 登录页路径和你erb里的Login链接对应即可
  const loginPath = '/users/sign_in';

  return (
    <div className="container">
      {data.reviewsAll.map((review) => (
        <article className="review" key={review.id}>
          <h2>
            <a href={`/reviews/${review.id}`}>{review.title}</a>
          </h2>
          <div className="myUrl">
            <a href={review.url}>{review.url}</a>
          </div>
          <div className="tagline">{review.tagline}</div>
          <footer>
            <button 
              onClick={() => {
                if (!isLoggedIn) {
                  // 未登录跳转到登录页
                  window.location.href = loginPath;
                  return;
                }
                // 已登录执行点赞逻辑
                upVote(review);
              }}
            >
              🔼 {review.votes} 
            </button>
          </footer>
        </article>
      ))}
    </div>
  );
}

renderComponent(ReviewsIndex);

方案2:ERB模板注入全局登录状态(更简单)

如果你不想依赖GraphQL返回登录状态,可以直接在Rails的布局模板里把登录状态注入到全局window对象,React组件直接读取即可:

第一步:修改application.html.erb

在head标签内新增如下脚本:

<head>
  <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
  <title>Kittynews</title>
  <%= csrf_meta_tags %>
  <%= stylesheet_link_tag 'application', media: 'all' %>
  <%= javascript_include_tag 'application' %>
  <!-- 新增:注入全局登录状态 -->
  <script>
    window.userSignedIn = <%= user_signed_in? ? 'true' : 'false' %>;
    window.currentUserId = <%= user_signed_in? ? current_user.id.to_json : 'null' %>;
  </script>
</head>

第二步:React组件内直接读取全局状态

把方案1里的isLoggedIn判断替换为:

const isLoggedIn = window.userSignedIn;

后续逻辑和方案1完全一致即可。


内容的提问来源于stack exchange,提问作者NBash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 13:24:06