1

I am a newcomer to Ruby on Rails but have an issue with ReactJs. I tried to use React-Router-DOM and Redux but got errors. One of the errors occurred with 'export default connect(structureSelector, mapDispatchToProps)(HelloWorld);'. Do you have any idea with this issue?

Error message

TypeError: Object(...) is not a function
    at Module../app/javascript/components/HelloWorld.js (HelloWorld.js:45)
    at __webpack_require__ (bootstrap:19)
    at webpackContext (.*$:11)
    at fromRequireContext.js:13
    at Object.getConstructor (fromRequireContextWithGlobalFallback.js:15)
    at Object.mountComponents (index.js:89)
    at HTMLDocument../node_modules/react_ujs/react_ujs/index.js.ReactRailsUJS.handleMount (index.js:149)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.pageLoaded (turbolinks.js:948)
ReferenceError: HelloWorld is not defined
    at eval (eval at ./node_modules/react_ujs/react_ujs/src/getConstructor/fromGlobal.js.module.exports (fromGlobal.js:12), <anonymous>:1:1)
    at ./node_modules/react_ujs/react_ujs/src/getConstructor/fromGlobal.js.module.exports (fromGlobal.js:12)
    at Object.getConstructor (fromRequireContextWithGlobalFallback.js:19)
    at Object.mountComponents (index.js:89)
    at HTMLDocument../node_modules/react_ujs/react_ujs/index.js.ReactRailsUJS.handleMount (index.js:149)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.pageLoaded (turbolinks.js:948)
    at turbolinks.js:872
ncaught Error: Cannot find component: 'HelloWorld'. Make sure your component is available to render.
    at Object.mountComponents (index.js:103)
    at HTMLDocument../node_modules/react_ujs/react_ujs/index.js.ReactRailsUJS.handleMount (index.js:149)
    at Object../node_modules/turbolinks/dist/turbolinks.js.e.dispatch (turbolinks.js:75)
    at r.notifyApplicationAfterPageLoad (turbolinks.js:994)
    at r.pageLoaded (turbolinks.js:948)
    at turbolinks.js:872

package.json*

{
  "name": "rails_react",
  "private": true,
  "dependencies": {
    "@babel/preset-react": "^7.8.3",
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "4.2.2",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "babel-polyfill": "^6.26.0",
    "prop-types": "^15.7.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-redux": "^7.1.3",
    "react-router-dom": "^5.1.2",
    "react_ujs": "^2.6.1",
    "redux": "^4.0.5",
    "reselect": "^4.0.0",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.10.3"
  }
}

routers.rb

Rails.application.routes.draw do
  root 'static#index'
  namespace :v1, defaults: { format: 'json'} do
    get 'things' => 'things#index'
  end

  get '*page' => 'static#index', constraints: -> (req) do
    !req.xhr? && req.format.html?
  end
end

configureStore.js

// Redux
import { createStore } from "redux";
import React from "react"

const initialState = {
    things: []
};

function rootReducer(state, action) {
    console.log(action.type);
    switch (action.type) {
        default:
            return state
    }
}

export default class configureStore extends React.Component {
    render() {
        //createStore(reducer, preloadedState)
        const store = createStore(rootReducer, initialState);
        return store;
    }
}

HelloWorld.js

import React, {useState} from "react"
import PropTypes from "prop-types"
import {connect} from "react-redux/lib/connect/connect"
import { createStructuredSelector } from "reselect";

const GET_REQUEST = 'Get request';

function getThings() {
  return {
    type: GET_REQUEST
  };
};

class HelloWorld extends React.Component {
  render() {
    return (
      <React.Fragment>
        Greeting: {this.props.greeting}

        {/* adding button */}
        <button className="getThingsBtn" onClick={() => 
          this.props.getThings()
        }>Get Things</button>
      </React.Fragment>
    );
  }
}
HelloWorld.propTypes = {
  greeting: PropTypes.string
};

const structureSelector = createStructuredSelector({
  things: state => state.things,
});

const mapDispatchToProps = { getThings };
export default connect(structureSelector, mapDispatchToProps)(HelloWorld);

App.js

import React from "react"
import PropTypes from "prop-types"
import HelloWorld from "./HelloWorld";
import { BrowserRouter, Switch, Route } from "react-router-dom";

import { Provider } from "react-redux";
import configureStore from "../configureStore";
const store = configureStore();

class App extends React.Component {
  render() {
    return (
      // Redux installed in your app with Provider
      <Provider store={store}>
        <BrowserRouter>
          <Switch>
            <Route exact path="/" render={() => ("Home")}></Route>
            <Route exact path="/hello" render={() => <HelloWorld greeting="App component" />}></Route>
          </Switch>
        </BrowserRouter>
      </Provider>
    );
  }
}

export default App

index.html.erb

// <%= react_component("HelloWorld", { greeting: "previous index"}) %>
//
<%= react_component("App")%>

After changing import with import {connect} from "react-redux";

Uncaught Invariant Violation: Could not find "store" in the context of "Connect(HelloWorld)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(HelloWorld) in connect options.
    at invariant (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:3710:15)
    at ConnectFunction (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:37392:55)
    at renderWithHooks (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:25350:22)
    at updateFunctionComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27396:24)
    at updateSimpleMemoComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27336:14)
    at updateMemoComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27241:18)
    at beginWork$1 (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:29269:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9369:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9418:20)
    at invokeGuardedCallback (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9471:35)
react-dom.development.js:21838 The above error occurred in the <ConnectFunction> component:
    in ConnectFunction

Consider adding an error boundary to your tree to customize error handling behavior.
Visit /react-error-boundaries to learn more about error boundaries.
logCapturedError @ react-dom.development.js:21838
react-dom.development.js:25204 Uncaught Invariant Violation: Could not find "store" in the context of "Connect(HelloWorld)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(HelloWorld) in connect options.
    at invariant (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:3710:15)
    at ConnectFunction (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:37392:55)
    at renderWithHooks (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:25350:22)
    at updateFunctionComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27396:24)
    at updateSimpleMemoComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27336:14)
    at updateMemoComponent (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:27241:18)
    at beginWork$1 (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:29269:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9369:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9418:20)
    at invokeGuardedCallback (http://localhost:3000/packs/js/application-bb3c5d4bd7a041206dc3.js:9471:35)
8
  • import {connect} from "react-redux/lib/connect/connect" this line seems odd, try using the standard: import { connect } from 'react-redux' i can see this as only possible issue. If this is a test app, upload it on github and share link, would be better if the above does not work. If above works, let me know and i will add this as answer. (not adding answer because i can't test this) Commented Feb 12, 2020 at 7:29
  • @ZiaUlRehmanMughal Thank you for your comment, This is the git address of this project (github.com/iyamus/ruby_react_200211). I referred to this site(github.com/reduxjs/react-redux/issues/1117) for change this "import {connect} from "react-redux/lib/connect/connect" Commented Feb 12, 2020 at 14:32
  • @Please tell me if you tried my suggestion, also the thread you linked say same as what I am saying: github.com/reduxjs/react-redux/issues/… Commented Feb 13, 2020 at 5:45
  • If my suggestion does not fix it, please add instructions to run/setup in the readme of the repo so i can try on that. Commented Feb 13, 2020 at 5:47
  • @ZiaUlRehmanMughal As your saying I updated, but get the error like the thread. You could see the error in content Commented Feb 13, 2020 at 6:03

1 Answer 1

1

As discussed in the comments and I tried it in the provided github repo, import is wrong.

Chnage

import {connect} from "react-redux/lib/connect/connect"

TO:

import { connect } from 'react-redux'

And it will fix this error, and should be enough of an answer to the question, following is bonus just as courtesy.

Bonus part

Than you will start getting other provider related errors in your code, that's because of the view file, which looks like:

// <%= react_component("HelloWorld", { greeting: "previous index"}) %>
//
<%= react_component("App")%>

2 issues here:

  1. // is not valid comments in erb(ruby), use # to comment, or remove the lines in their entirety. And app runs fine.
  2. If you want to render HelloWorld component without rendering app, than you need to provide specific store in HelloWorld component, that's not the topic here and not something to be explained in SO, it is about basic of using redux/store/provider etc.

So just first the import and follow point 1 above, and your app will render fine, i tested it on your repo.

Sign up to request clarification or add additional context in comments.

3 Comments

My app still has a problem with render using 'import { connect } from 'react-redux'.It's about 'Uncaught Invariant Violation: Could not find "store" in the context of "Connect(HelloWorld)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(HelloWorld) in connect options.' But thank you.
Yes bonus part is about this issue, it is not because of import @Frames, as i tried to explain, it is when you render Helloworld component directly, just render app and remove ...react_component("HelloWorld"... line from your view file, as mentioned in my answer.
@Frames Besides, here on SO, you don't get to fix all the errors in your code in one post, the format here is to solve one error at a time through questions, that also if you can't find answers to that error in your own search. The invariant violation is another error and very common, occurs because of misuse of redux, you should be able to find plenty of resources on the internet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.