如何让Rails向React的Axios请求返回实例变量而非HTML响应
Hey there! Let's tackle your two main concerns here—first confirming if your React component structure fits Rails best practices, then fixing that Axios issue where you're getting full HTML instead of your test message.
React Component Import Style in Rails
Good news: your preferred tree-style component import (starting with a single entry file and importing nested components from there) is totally valid in Rails!
If you're using Rails 7+, you're likely working with jsbundling-rails (the default JS tooling) which uses webpack, esbuild, or rollup—all of which support ES module imports just like Express. As long as you're using relative paths correctly (e.g., importing a child component with import ChildComponent from './ChildComponent' inside your Index.jsx), this structure will work seamlessly.
One quick note: if you're using the react-rails gem to render components with react_component('Index'), make sure you've registered your component in your main JS entrypoint (usually app/javascript/application.js):
import React from "react" import { registerComponent } from 'react-rails' import Index from './components/Index' // Register the component so react-rails can find it registerComponent('Index', () => Index)
This step ensures Rails can map the component name you pass to react_component to your actual JSX file.
Fixing the Axios HTML Response Issue
The reason you're getting full HTML instead of your test string is that Rails controllers automatically try to render a corresponding view template by default. Your LoginController#index is looking for views/login/index.html.erb (even if it doesn't exist, it might fall back to a default or error page as HTML). To return raw data, you need to explicitly tell Rails to render JSON instead.
Update your login_controller.rb like this:
class LoginController < ApplicationController def index @test = 'TESTING MY RAILS ROUTE' # Explicitly render JSON instead of looking for a view template render json: { message: @test } end end
Then, in your Axios callback, you can access the message directly:
axios.get('/login') .then(res => { console.log(res.data.message) // This will log 'TESTING MY RAILS ROUTE' })
If you just want to return the raw string instead of an object, simplify the controller line to:
render json: @test
Then console.log(res.data) will log the string directly.
Bonus: Clean Up Your Routes
Since you only need a single GET /login route for this request, you can simplify your config/routes.rb from resources :login (which creates 7 unused CRUD routes) to:
Rails.application.routes.draw do get 'welcome/index' get 'login', to: 'login#index' # Only create the route you need root 'welcome#index' end
That's it! After these changes, your Axios request should return the expected test message instead of HTML, and your React component structure will work just like you're used to in Express.
内容的提问来源于stack exchange,提问作者Naji

