Ruby в Rails с React «Ошибка типа: ошибка объекта (...) не является функцией») - PullRequest
0 голосов
/ 12 февраля 2020

Я новичок в Ruby на Rails, но у меня проблема с ReactJs. Я пытался использовать React-Router-DOM и Redux, но получил ошибки. Одна из ошибок произошла с «экспортировать соединение по умолчанию (structureSelector, mapDispatchToProps) (HelloWorld);». У вас есть идеи по этому вопросу?

Сообщение об ошибке

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

пакет. 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);

Приложение. 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")%>

После изменения импорта с помощью import {connect} из "act-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)

1 Ответ

1 голос
/ 13 февраля 2020

Как обсуждено в комментариях, и я попробовал это в предоставленном репозитории github, импорт неправильный.

Chnage

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

TO:

import { connect } from 'react-redux'

И это исправит эту ошибку, и должно быть достаточно ответа на вопрос, следующий бонус так же, как любезность.

Бонус часть

Чем вы начнете получать ошибки, связанные с другими провайдерами, в вашем коде, это связано с файлом представления, который выглядит следующим образом:

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

2 здесь:

  1. // - недопустимые комментарии в erb (ruby), используйте #, чтобы комментировать, или удалите строки целиком. И приложение работает нормально.
  2. Если вы хотите визуализировать HelloWorld компонент без приложения для рендеринга, чем вам нужно предоставить конкретное c хранилище в HelloWorld компоненте, это не topi c здесь и не что-то, что нужно объяснить в SO, это примерно 1040 * использования redux / store / provider et c.

Итак, сначала выполните импорт и следуйте пункту 1 выше, и ваше приложение будет нормально работать, я проверил его на вашем репо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...