MCPcopy
hub / github.com/reactjs/react-rails

github.com/reactjs/react-rails @v2.6.2 sqlite

repository ↗ · DeepWiki ↗ · release v2.6.2 ↗
2,327 symbols 7,207 edges 84 files 216 documented · 9%
README

React-Rails

Gem npm Build Status Maintainers Wanted

React-Rails is a flexible tool to use React with Rails. The benefits: * Automatically renders React server-side and client-side * Supports Webpacker 4.x, 3.x, 2.x, 1.1+ * Supports Sprockets 4.x, 3.x, 2.x * Lets you use JSX, ES6, TypeScript, CoffeeScript

A source code example utilizing React-Rails: https://github.com/BookOfGreg/react-rails-example-app

Contents

After reading this README file, additional information about React-Rails can be found in the Wiki page: https://github.com/reactjs/React-Rails/wiki The Wiki page features a significant amount of additional information about React-Rails which includes instructional articles and answers to the most frequently asked questions.

Get started with Webpacker

Alternatively, get started with Sprockets

Webpacker provides modern JS tooling for Rails. Here are the listed steps for integrating Webpacker and Rails-React with Rails:

1) Create a new Rails app:
$ rails new my-app
$ cd my-app
2) Add react-rails to your Gemfile:
gem 'react-rails'

Note: On rails versions < 6.0, You need to add gem 'webpacker' to your Gemfile in step 2 above.

3) Now run the installers:
Rails 6.x and 5.x:
$ bundle install
$ rails webpacker:install         # OR (on rails version < 5.0) rake webpacker:install
$ rails webpacker:install:react   # OR (on rails version < 5.0) rake webpacker:install:react
$ rails generate react:install

This gives you:

  • app/javascript/components/ directory for your React components
  • ReactRailsUJS setup in app/javascript/packs/application.js
  • app/javascript/packs/server_rendering.js for server-side rendering

Note: On rails versions < 6.0, link the JavaScript pack in Rails view using javascript_pack_tag helper:


<%= javascript_pack_tag 'application' %>
4) Generate your first component:
$ rails g react:component HelloWorld greeting:string
5) You can also generate your component in a subdirectory:
$ rails g react:component my_subdirectory/HelloWorld greeting:string

Note: Your component is added to app/javascript/components/ by default.

Note: If your component is in a subdirectory you will append the directory path to your erb component call.

Example:

<%= react_component("my_subdirectory/HelloWorld", { greeting: "Hello from react-rails." }) %>
6) Render it in a Rails view:

<%= react_component("HelloWorld", { greeting: "Hello from react-rails." }) %>
7) Lets Start the app:
$ rails s

output: greeting: Hello from react-rails", inspect webpage in your browser too see change in tag props.

Component name

The component name tells react-rails where to load the component. For example:

react_component call component require
react_component("Item") require("Item")
react_component("items/index") require("items/index")
react_component("items.Index") require("items").Index
react_component("items.Index.Header") require("items").Index.Header

This way, you can access top-level, default, or named exports.

The require.context inserted into packs/application.js is used to load components. If you want to load components from a different directory, override it by calling ReactRailsUJS.useContext:

var myCustomContext = require.context("custom_components", true)
var ReactRailsUJS = require("react_ujs")
// use `custom_components/` for <%= react_component(...) %> calls
ReactRailsUJS.useContext(myCustomContext)

If require fails to find your component, ReactRailsUJS falls back to the global namespace, described in Use with Asset Pipeline.

File naming

React-Rails supports plenty of file extensions such as: .js, .jsx.js, .js.jsx, .es6.js, .coffee, etcetera! Sometimes this will cause a stumble when searching for filenames.

Component File Name react_component call
app/javascript/components/samplecomponent.js react_component("samplecomponent")
app/javascript/components/sample_component.js react_component("sample_component")
app/javascript/components/SampleComponent.js react_component("SampleComponent")
app/javascript/components/SampleComponent.js.jsx Has to be renamed to SampleComponent.jsx, then use react_component("SampleComponent")

Typescript support

If you want to use React-Rails with Typescript, simply run the installer and add @types:

$ bundle exec rails webpacker:install:typescript
$ yarn add @types/react @types/react-dom

Doing this will allow React-Rails to support the .tsx extension. Additionally, it is recommended to add ts and tsx to the server_renderer_extensions in your application configuration:

config.react.server_renderer_extensions = ["jsx", "js", "tsx", "ts"]

Test component

You can use assert_react_component to test component render:

app/views/welcome/index.html.erb

<%= react_component("HelloWorld", { greeting: "Hello from react-rails.", info: { name: "react-rails" } }, { class: "hello-world" }) %>
class WelcomeControllerTest < ActionDispatch::IntegrationTest
  test 'assert_react_component' do
    get "/welcome"
    assert_equal 200, response.status

    # assert rendered react component and check the props
    assert_react_component "HelloWorld" do |props|
      assert_equal "Hello from react-rails.", props[:greeting]
      assert_equal "react-rails", props[:info][:name]
      assert_select "[class=?]", "hello-world"
    end

    # or just assert component rendered
    assert_react_component "HelloWorld"
  end
end

Use with Asset Pipeline

react-rails provides a pre-bundled React.js & a UJS driver to the Rails asset pipeline. Get started by adding the react-rails gem:

gem 'react-rails'

And then install the react generator:

$ rails g react:install

Then restart your development server.

This will:

  • add some //= requires to application.js
  • add a components/ directory for React components
  • add server_rendering.js for server-side rendering

Now, you can create React components in .jsx files:

// app/assets/javascripts/components/post.jsx

window.Post = createReactClass({
  render: function() {
    return <h1>{this.props.title}</h1>
  }
})

// or, equivalent:
class Post extends React.Component {
  render() {
    return <h1>{this.props.title}</h1>
  }
}

Then, you can render those components in views:

<%= react_component("Post", {title: "Hello World"}) %>

Components must be accessible from the top level, but they may be namespaced, for example:

<%= react_component("Comments.NewForm", {post_id: @post.id}) %>

Custom JSX Transformer

react-rails uses a transformer class to transform JSX in the asset pipeline. The transformer is initialized once, at boot. You can provide a custom transformer to config.react.jsx_transformer_class. The transformer must implement:

  • #initialize(options), where options is the value passed to config.react.jsx_transform_options
  • #transform(code_string) to return a string of transformed code

react-rails provides two transformers, React::JSX::BabelTransformer (which uses ruby-babel-transpiler) and React::JSX::JSXTransformer (which uses the deprecated JSXTransformer.js).

Transform Plugin Options

To supply additional transform plugins to your JSX Transformer, assign them to config.react.jsx_transform_options

react-rails uses the Babel version of the babel-source gem.

For example, to use babel-plugin-transform-class-properties :

config.react.jsx_transform_options = {
  optional: ['es7.classProperties']
}

React.js versions

//= require react brings React into your project.

By default, React's [development version] is provided to Rails.env.development. You can override the React build with a config:

# Here are the defaults:
# config/environments/development.rb
MyApp::Application.configure do
  config.react.variant = :development
end

# config/environments/production.rb
MyApp::Application.configure do
  config.react.variant = :production
end

Be sure to restart your Rails server after changing these files. See VERSIONS.md to learn which version of React.js is included with your react-rails version. In some edge cases you may need to bust the sprockets cache with rake tmp:clear

View Helper

react-rails includes a view helper and an unobtrusive JavaScript driver which work together to put React components on the page.

The view helper (react_component) puts a div on the page with the requested component class & props. For example:

<%= react_component('HelloMessage', name: 'John') %>






On page load, the react_ujs driver will scan the page and mount components using data-react-class and data-react-props.

The view helper's signature is:

react_component(component_class_name, props={}, html_options={})
  • component_class_name is a string which identifies a component. See getConstructor for details.
  • props is either:
  • an object that responds to #to_json; or
  • an already-stringified JSON object (see JBuilder note below).
  • html_options may include:
  • tag: to use an element other than a div to embed data-react-class and data-react-props.
  • prerender: true to render the component on the server.
  • camelize_props to transform a props hash
  • **other Any other arguments (eg class:, id:) are passed through to content_tag.

Custom View Helper

react-rails uses a "helper implementation" class to generate the output of the react_component helper. The helper is initialized once per request and used for each react_component call during that request. You can provide a custom helper class to config.react.view_helper_implementation. The class must implement:

  • #react_component(name, props = {}, options = {}, &block) to return a string to inject into the Rails view
  • #setup(controller_instance), called when the helper is initialized at the start of the request
  • #teardown(controller_instance), called at the end of the request

react-rails provides one implementation, React::Rails::ComponentMount.

UJS

react-rails's JavaScript is available as "react_ujs" in the asset pipeline or from NPM. It attaches itself to the window as ReactRailsUJS.

Mounting & Unmounting

Usually, react-rails mounts & unmounts components automatically as described in Event Handling below.

You can also mount & unmount components from <%= react_component(...) %> tags using UJS:

// Mount all components on the page:
ReactRailsUJS.mountComponents()
// Mount components within a selector:
ReactRailsUJS.mountComponents(".my-class")
// Mount components within a specific node:
ReactRailsUJS.mountComponents(specificDOMnode)

// Unmounting works the same way:
ReactRailsUJS.unmountComponents()
ReactRailsUJS.unmountComponents(".my-class")
ReactRailsUJS.unmountComponents(specificDOMnode)

You can use this when the DOM is modified by AJAX calls or modal windows.

Event Handling

ReactRailsUJS checks for various libraries to support their

Core symbols most depended-on inside this repo

error
called by 210
lib/assets/react-source/development/react.js
match
called by 171
lib/assets/javascripts/JSXTransformer.js
markerApply
called by 170
lib/assets/javascripts/JSXTransformer.js
r
called by 127
lib/assets/react-source/production/react.js
expect
called by 119
lib/assets/javascripts/JSXTransformer.js
markerCreate
called by 116
lib/assets/javascripts/JSXTransformer.js
lex
called by 95
lib/assets/javascripts/JSXTransformer.js
throwError
called by 93
lib/assets/javascripts/JSXTransformer.js

Shape

Function 2,324
Class 2
Method 1

Languages

TypeScript100%

Modules by API surface

lib/assets/react-source/development/react.js1,294 symbols
lib/assets/javascripts/JSXTransformer.js412 symbols
lib/assets/react-source/production/react.js307 symbols
lib/assets/react-source/development/react-server.js261 symbols
lib/assets/react-source/production/react-server.js28 symbols
lib/assets/javascripts/react_ujs.js6 symbols
react_ujs/src/renderHelpers.js5 symbols
lib/react/server_rendering/bundle_renderer/timeout_polyfill.js4 symbols
test/dummy_webpacker3/app/javascript/components/export_default_component.js3 symbols
test/dummy_webpacker3/app/assets/javascripts/harmony_example.js.jsx2 symbols
test/dummy_sprockets/app/assets/javascripts/harmony_example.js.jsx2 symbols
test/helper_files/WithoutSprockets.js1 symbols

Dependencies from manifests, versioned

@rails/webpacker3.0.1 · 1×
autoprefixer7.1.1 · 1×
babel-core6.24.1 · 1×
babel-loader7.x · 1×
babel-polyfill6.23.0 · 1×
babel-preset-env1.4.0 · 1×
babel-preset-react6.24.1 · 1×
coffee-loader0.7.3 · 1×
coffee-script1.12.6 · 1×
compression-webpack-plugin0.4.0 · 1×
create-react-class15.6.2 · 1×
css-loader0.28.1 · 1×

For agents

$ claude mcp add react-rails \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact