react-rails: Cannot find component (Rails 5.1.2, webpacker, react-rails)
Help us help you! Please choose one:
- My app crashes with
react-rails, so I’ve included the stack trace and the exact steps which make it crash. - My app doesn’t crash, but I’m getting unexpected behavior. So, I’ve described the unexpected behavior and suggested a new behavior.
- I’m trying to use
react-railswith another library, but I’m having trouble. I’ve described my JavaScript management setup (eg, Sprockets, Webpack…), how I’m trying to use this other library, and why it’s not working. - I have another issue to discuss.
Essentially the same resulting problem as #757 and #713, where including my (haml) view helper = react_component 'PerformanceRow' gives me the following error messages:
Error: Cannot find module './PerformanceRow'.
at webpackContextResolve (application.js:4549)
at webpackContext (application.js:4544)
at eval (fromRequireContext.js?f05c:13)
at Object.eval [as getConstructor] (fromRequireContextWithGlobalFallback.js?7c97:13)
at Object.mountComponents (index.js?0542:82)
at HTMLDocument.ReactRailsUJS.handleMount (index.js?0542:124)
at HTMLDocument.dispatch (event.js?268c:338)
at HTMLDocument.elemData.handle (event.js?268c:146)
fromRequireContextWithGlobalFallback.js?7c97:20 ReferenceError: PerformanceRow is not defined
at eval (eval at module.exports (fromGlobal.js?7c2e:22), <anonymous>:1:1)
at module.exports (fromGlobal.js?7c2e:13)
at Object.eval [as getConstructor] (fromRequireContextWithGlobalFallback.js?7c97:17)
at Object.mountComponents (index.js?0542:82)
at HTMLDocument.ReactRailsUJS.handleMount (index.js?0542:124)
at HTMLDocument.dispatch (event.js?268c:338)
at HTMLDocument.elemData.handle (event.js?268c:146)
index.js?0542:89 [react-rails] Cannot find component: 'PerformanceRow' for element <div data-react-class="PerformanceRow" data-react-props="{"id":5}"></div>
index.js?0542:91 Uncaught Error: Cannot find component: 'PerformanceRow'. Make sure your component is available to render.
at Object.mountComponents (index.js?0542:91)
at HTMLDocument.ReactRailsUJS.handleMount (index.js?0542:124)
at HTMLDocument.dispatch (event.js?268c:338)
at HTMLDocument.elemData.handle (event.js?268c:146)
I’ve tried the following:
- Rolling back uglifier to 3.0
- Moving the
ReactRailsUJSboth above and belowimport "turbolinks"andjavascript_include_tag "application.js"in my mainviews/layouts/application.html.haml, and removing/addingReactRailsUJS.detectEvents()inapp/javascript/packs/application.js. - Adding
console.log(componentRequireContext.keys())above theReactRailsUJSinitializer, which prints["./PerformanceRow.jsx"]in my Chrome console.
Here’s my directory structure:
app/javascript/packs/
├── application.js
├── hello_react.jsx
└── server_rendering.js
app/javascript/components/
└── PerformanceRow.jsx
And some code:
// app/javascript/packs/application.js
import ReactRailsUJS from 'react_ujs'
// Support component names relative to this directory:
var componentRequireContext = require.context("components", true, /\.jsx?$/)
// => prints ["./PerformanceRow.jsx"] in Chrome console
console.log(componentRequireContext.keys());
ReactRailsUJS.useContext(componentRequireContext)
// app/javascript/components/PerformanceRow.jsx
import React, { Component } from "react"
import ReactDOM from "react-dom"
class PerformanceRow extends Component {
render() {
return (
<tr className="performance">
<td>HEY THERE</td>
<td />
<td />
<td>Delete</td>
</tr>
)
}
}
export default PerformanceRow;
-# Extract from app/views/performances/_embedded_form.html.haml
= react_component 'PerformanceRow'
As far as I can tell, I’ve double-checked capitalization and name-mangling, and componentRequireContext can definitely find the correct file. However, PerformanceRow still seems to be unreachable. I can also access ReactRailsUJS in the global context of the Chrome console.
I should also mention that the default hello_react.jsx works just fine, but that the problem here seems to lie in ReactRailsUJS and the use of the components/ directory. Tried to trim things as best I could, but let me know if I need to include any other information.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 21
- Comments: 23 (6 by maintainers)
Commits related to this issue
- Fix #758 - Find .jsx component files If the original `fileName` search doesn't work, look for the file with `.jsx` on the end. This makes it possible to include `.jsx` files in the `app/javascript/co... — committed to andrewcsmith/react-rails by andrewcsmith 7 years ago
- Fix #758 Find .jsx component files — committed to andrewcsmith/react-rails by andrewcsmith 7 years ago
- Fix fromRequireContext to add .jsx extension It's the patch from https://github.com/reactjs/react-rails/pull/759 that was never merged to master, but I still need. — committed to loveland/react-rails by quidquid 5 years ago
If you have this issue, and the above did not solve it, it may be because you previously installed react-rails to work with the rails asset pipeline, and then installed webpacker later.
Removing
//= require reactand//= require react_ujsfromapplication.jsorapplication.js.coffeefixed this for me.I’m assuming that having
reactand especiallyreact_ujsin the asset pipeline meant thatReactRailsUJSwas being set up to expect components also from the asset pipeline, and that setup was taking precedence over the webpacker setup.I was forced to adjust my regex to allow directories to be included, as well as the JavaScript/Typescript files themselves:
I am not fond of this solution though, I feel like react-rails should be able to load components by name if the regex excludes directories but loads files.
Update: I was wrong about the above, it does work with
.jsxbut I was importing the files directly with their name without any folder just as it’s done with the asset pipeline, but it seems that with Webpacker (or at least my setup) you need to specify the folder they’re on too:This seems a bit odd since I didn’t read anything about adding folders in the
react-railsdocumentation 🤔I installed both at the same time, and didn’t have either in the asset pipeline. In the original problem,
react-railswas finding components with.jsextensions, just not.jsxextensions. Wonder why that would do it.@BookOfGreg I run into this problem when I apply filtering to
require.context()to only load production JS/JSX/TS/TSX files in my application pack. The main purpose of me doing this is to have my test files/folders excluded from asset compilation, since they shouldn’t be shipped to production. My plight with passing the appropriate filter regex torequire.contextis documented here: https://github.com/rails/webpacker/issues/1818#issuecomment-576428973Unfortunately, I then run into a problem with
react-rails, in that my calls toreact_componentstarted failing. I have a hunch it is due to directory names no longer being loaded byrequire.context, but I’m not too sure. Anyway, I hope that this provides you with another angle to think about this problem.I am happy to delve further into reproduction steps with you.