React.createElement: Typ ist ungültig - erwartet eine Zeichenfolge


98

Der Versuch, React-Router (v4.0.0) und React-Hot-Loader (3.0.0-Beta.6) zum Spielen zu bringen, zeigt jedoch den folgenden Fehler in der Browserkonsole an:

Warnung: React.createElement: Typ ist ungültig - erwartet eine Zeichenfolge (für integrierte Komponenten) oder eine Klasse / Funktion (für zusammengesetzte Komponenten), hat aber: undefiniert. Sie haben wahrscheinlich vergessen, Ihre Komponente aus der Datei zu exportieren, in der sie definiert ist.

index.js:

import React from 'react';
import ReactDom from 'react-dom';
import routes from './routes.js';
require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import './css/main.css';

const renderApp = (appRoutes) => {
    ReactDom.render(appRoutes, document.getElementById('root'));
};

renderApp( routes() );

route.js:

import React from 'react';
import { AppContainer } from 'react-hot-loader';
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
import store from './store/store.js';
import { Provider } from 'react-redux';
import App from './containers/App.jsx';
import Products from './containers/shop/Products.jsx';
import Basket from './containers/shop/Basket.jsx';

const routes = () => (

    <AppContainer>
        <Provider store={store}>
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRoute component={Products} />
                    <Route path="/basket" component={Basket} />
                </Route>
            </Router>
        </Provider>
    </AppContainer>

);

export default routes;

Wenn Sie react-router-config verwenden, stellen Sie sicher, dass Sie die componentEigenschaft anstelle von verwenden render, da das Paket die spätere Version nicht unterstützt. Sehen Sie mehr auf GitHub .
Totymedli

Antworten:


126

Meistens liegt dies an einem falschen Export / Import.

Häufiger Fehler:

// File: LeComponent.js
export class LeComponent extends React.Component { ... }

// File: App.js
import LeComponent from './LeComponent';

Mögliche Option:

// File: LeComponent.js 
export default class LeComponent extends React.Component { ... }

// File: App.js
import LeComponent from './LeComponent';

Es gibt einige Möglichkeiten, wie es falsch sein könnte, aber dieser Fehler ist jedes Mal in 60% der Fälle auf eine Nichtübereinstimmung zwischen Import und Export zurückzuführen.

Bearbeiten

In der Regel sollten Sie eine Stapelverfolgung erhalten, die einen ungefähren Ort angibt, an dem der Fehler auftritt. Dies folgt in der Regel direkt nach der Nachricht, die Sie in Ihrer ursprünglichen Frage haben.

Wenn es nicht angezeigt wird, lohnt es sich möglicherweise zu untersuchen, warum (es kann sich um eine Build-Einstellung handeln, die Sie vermissen). Unabhängig davon, wenn dies nicht angezeigt wird, besteht die einzige Vorgehensweise darin, einzugrenzen, wo der Export / Import fehlschlägt.

Leider besteht die einzige Möglichkeit, dies ohne Stacktrace zu tun, darin, jedes Modul / Submodul manuell zu entfernen, bis Sie den Fehler nicht mehr erhalten, und sich dann den Stapel wieder hochzuarbeiten.

Bearbeiten 2

Über Kommentare war es in der Tat ein Importproblem, insbesondere das Importieren eines Moduls, das nicht existierte


Habe mir die Spur angesehen, die auf Zeile 12 von route.js zeigt. Diese Zeile ist<IndexRoute component={Products} />
JoeTidee

2
Sind Sie sicher, dass die Indexroute tatsächlich Teil von RR4 ist? (Ich bin mir ziemlich sicher, dass es nicht so ist)
Chris

Das war das Problem - danke! Ich bin zurück zu v3.0.0
JoeTidee

Tolles, gutes Zeug. Fühlen Sie sich frei, es als akzeptierte Antwort zu markieren, da es zukünftigen Lesern helfen wird, ähnliche Probleme anzugehen
Chris

1
@PriyaRanjanSingh Es ist unmöglich, nur einen kleinen Kommentar zu sagen. Können Sie eine neue Frage mit Details posten?
Chris

16

Ich habe auch diesen Fehler bekommen.

Ich habe verwendet:

import BrowserRouter from 'react-router-dom';

Fix tat dies stattdessen:

import { BrowserRouter } from 'react-router-dom';


11

Versuche dies

npm i react-router-dom@next

in Ihrer App.js.

import { BrowserRouter as Router, Route } from 'react-router-dom'

const Home = () => <h1>Home</h1>

const App = () =>(
  <Router>
    <Route path="/" component={Home} />
  </Router>
)

export default App;


4

Ich hatte dieses Problem, als ich eine CSS-Datei zum selben Ordner wie die Komponentendatei hinzufügte.

Meine Importanweisung war:

import MyComponent from '../MyComponent'

Das war in Ordnung, wenn es nur eine einzige Datei gab, MyComponent.jsx. (Ich habe dieses Format in einem Beispiel gesehen und ausprobiert und dann vergessen, dass ich es getan habe.)

Wenn ich MyComponent.scss zum selben Ordner hinzufügte, schlug der Import fehl. Möglicherweise hat JavaScript stattdessen die .scss-Datei geladen, sodass kein Fehler aufgetreten ist.

Mein Fazit: Geben Sie immer die Dateierweiterung an, auch wenn es nur eine Datei gibt, falls Sie später eine weitere hinzufügen.


3

Für zukünftige Googler:

Meine Lösung für dieses Problem bestand darin, ein Upgrade reactund react-domdie neuesten Versionen auf NPM durchzuführen. Anscheinend habe ich eine Komponente importiert, die die neue Fragmentsyntax verwendet und in meiner älteren Version von React fehlerhaft war.


2

Dieses Problem ist mir aufgetreten, als ich in meiner Render- / Return-Anweisung eine schlechte Referenz hatte. (Zeigen Sie auf eine nicht vorhandene Klasse). Überprüfen Sie auch Ihren Rückkehranweisungscode auf fehlerhafte Referenzen.


2

Meistens weist dies auf einen Import- / Exportfehler hin. Achten Sie jedoch nicht nur darauf, dass die referenzierte Datei im Stack-Trace selbst gut exportiert wird, sondern auch darauf, dass diese Datei andere Komponenten korrekt importiert . In meinem Fall war der Fehler wie folgt:

import React from 'react';

// Note the .css at the end, this is the cause of the error!
import SeeminglyUnimportantComponent from './SeeminglyUnimportantComponent.css';

const component = (props) => (            
  <div>
    <SeeminglyUnimportantComponent />
    {/* ... component code here */}
  </div>    
);

export default component;


Vielen Dank für diesen Kommentar! Ich habe dieses Problem seit dem Aktualisieren einiger Pakete, und ich habe alle diese Kommentare durchgeblättert, und keiner von ihnen ist in diesem Code in Frage. Aber das war es - die Problemdatei importiert etwas anderes, das den Fehler verursacht!
Diane Kaplan

2

Ich denke, das Wichtigste bei der Fehlerbehebung ist, dass er sich manifestiert, wenn Sie versuchen, eine nicht vorhandene Komponente zu instanziieren. Diese Komponente muss nicht importiert werden. In meinem Fall habe ich Komponenten als Eigenschaften übergeben. Ich habe vergessen, einen der Aufrufe zu aktualisieren, um die Komponente nach einigen Umgestaltungen ordnungsgemäß zu übergeben. Da JS nicht statisch typisiert ist, wurde mein Fehler leider nicht abgefangen, und es dauerte einige Zeit, um herauszufinden, was geschah.

Um diesen Fehler zu beheben, überprüfen Sie die Komponente, bevor Sie sie rendern, um sicherzustellen, dass es sich um den erwarteten Komponententyp handelt.


"Es manifestiert sich, wenn Sie versuchen, eine Komponente zu instanziieren, die nicht existiert" - das ist mir passiert. Die Komponente wurde importiert / korrekt exportiert , aber ich war es als Stütze durch eine Genehmigung Route verläuft in reagieren-Router und vergessen haben , die sich ändern render={props => <Component {...props} />}zu component={Component}.
Vertriebene

2

Mir fehlte ein Reaktionsfragment :


function Bar({ children }) {

  return (
    <div>
     {children}
    </div>
  );
}

function Foo() {
  return (
    <Bar>
      <Baz/>
      <Qux/>
    </Bar>
  );
}

Der obige Code löst den obigen Fehler aus. Aber das behebt es:

<Bar>
  <>
    <Baz/>
    <Qux/>
  </>
</Bar>

Ist mir passiert, als ich ReactCollapsingTable ( yarn add react-collapsing-table) hinzugefügt habe . Ich habe es geschafft, zwischen dieser Warnung (die zu einem Hydratationsfehler führte) und einem 'Fenster ist nicht definiert' zu wechseln, das im kompilierten Modul für <div>...</div>
reaktionskollabierende

Schließlich habe ich das gesamte Projekt von Anfang an neu transpiliert (anstelle von Hot-Reload) und das Problem trat erneut auf. Die Lösung finden Sie hier: stackoverflow.com/a/43969990/2821963 (anstelle von import module from 'module-name'verwenden require(module-name).default)
Superk

1

Was mir fehlte, war, dass ich benutzte

import { Router, Route, browserHistory, IndexRoute } from 'react-router';

stattdessen oder richtige Antwort sollte sein:

import { BrowserRouter as Router, Route } from 'react-router-dom';

Natürlich müssen Sie das npm-Paket react-router-dom hinzufügen :

npm install react-router-dom@next --save

1

In meinem Fall habe ich vergessen, meine (neuen) Elemente, die vom Render aufgerufen wurden, in die Datei index.js zu importieren und zu exportieren.


1

Array von Komponenten

Ein häufiger Weg, um diesen Fehler zu erhalten, ist die Verwendung eines Arrays von Komponenten mit einem Positionsindex , mit dem die zu rendernde Komponente aus dem Array ausgewählt wird. Ich habe so einen Code oft gesehen:

const checkoutSteps = [Address, Shipment, Payment]

export const Checkout = ({step}) => {

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Dies ist kein notwendiger fehlerhafter Code, aber wenn Sie ihn mit einem falschen Index aufrufen (z. B. -1oder 3in diesem Fall), wird die ToRenderKomponente undefinedden React.createElement: type is invalid...Fehler auslösen:

<Checkout step={0} /> // <Address />
<Checkout step={1} /> // <Shipment />
<Checkout step={2} /> // <Payment />
<Checkout step={3} /> // undefined
<Checkout step={-1} /> // undefined

Eine rationale Lösung

Sie sollten sich und Ihre Kollegen mit einem expliziteren Ansatz vor diesem schwer zu debuggenden Code schützen , magische Zahlen vermeiden und PropTypes verwenden:

const checkoutSteps = {
  address: Address,
  shipment Shipment,
  payment: Payment
}

const propTypes = {
  step: PropTypes.oneOf(['address', 'shipment', 'payment']),
}

/* TIP: easier to maintain
const propTypes = {
  step: PropTypes.oneOf(Object.keys(checkoutSteps)),
}
*/

const Checkout = ({step}) => {

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Checkout.propTypes = propTypes

export default Checkout

Und Ihr Code sieht folgendermaßen aus:

// OK
<Checkout step="address" /> // <Address />
<Checkout step="shipment" /> // <Shipment />
<Checkout step="payment" /> // <Payment />

// Errors
<Checkout step="wrongstep" /> // explicit error "step must be one of..."
<Checkout step={3} /> // explicit error (same as above)
<Checkout step={myWrongVar} /> // explicit error (same as above)

Vorteile dieses Ansatzes

  • Code ist expliziter , Sie können deutlich sehen, was Sie rendern möchten
  • Sie müssen sich die Zahlen und ihre verborgene Bedeutung nicht merken ( 1steht für Adresse, 2 steht für ...)
  • Fehler sind ausdrücklich zu
  • Keine Kopfschmerzen für deine Kollegen :)

0

In meinem Fall war die Reihenfolge wichtig, in der Sie die Komponente erstellen und rendern. Ich habe die Komponente gerendert, bevor ich sie erstellt habe. Am besten erstellen Sie die untergeordnete Komponente und dann die übergeordneten Komponenten und rendern dann die übergeordnete Komponente. Das Ändern der Reihenfolge hat das Problem für mich behoben.


0

In meinem Fall musste ich nur ein Upgrade von react-router-reduxauf durchführen react-router-redux@next. Ich gehe davon aus, dass es sich um ein Kompatibilitätsproblem handelt.


0

In einfachen Worten, irgendwie passiert Folgendes:

render() {
    return (
        <MyComponent /> // MyComponent is undefined.
    );
}

Es muss nicht unbedingt mit einem falschen Import oder Export zusammenhängen:

render() {
    // MyComponent may be undefined here, for example.
    const MyComponent = this.wizards[this.currentStep];

    return (
        <MyComponent />
    );
}

0

Wenn beim Testen einer Komponente dieser Fehler auftritt, stellen Sie sicher, dass jede untergeordnete Komponente korrekt ausgeführt wird, wenn sie alleine ausgeführt wird. Wenn eine Ihrer untergeordneten Komponenten von externen Ressourcen zum Rendern abhängt, versuchen Sie, sie mit einem Scherz oder einer anderen verspottenden Bibliothek zu verspotten:

Beispiel:

jest.mock('pathToChildComponent', () => 'mock-child-component')

0

In meinem Fall ist der Fehler beim Versuch aufgetreten, ContextApi zu verwenden. Ich habe fälschlicherweise verwendet:

const MyContext = () => createContext()

Aber es sollte definiert worden sein als:

const MyContext = createContext()

Ich poste es hier, damit zukünftige Besucher, die an einem so dummen Fehler hängen bleiben, es hilfreich finden, stundenlange Kopfschmerzen zu vermeiden, da dies nicht durch falschen Import / Export verursacht wird.


0

Auch die zirkuläre Abhängigkeit ist einer der Gründe dafür. [allgemein]


0

Dies ist ein Fehler, der in gewisser Weise behoben werden musste. Wie schon oft gesagt, kann ein unsachgemäßer Import / Export diesen Fehler verursachen, aber überraschenderweise habe ich diesen Fehler durch einen kleinen Fehler in react-router-dom authentication setupmeinem Fall erhalten:

FALSCHES SETUP:

const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
        {...rest}
        render={(props) => (token ? <Component {...props} /> : <Redirect to={{ pathname: "/login" }} />)}
    />
);

RICHTIGE EINSTELLUNG:

const PrivateRoute = ({ component: Component, token, ...rest }) => (
    <Route
        {...rest}
        render={(props) => (token ? <Component {...props} /> : <Redirect to={{ pathname: "/login" }} />)}
    />
);

Der einzige Unterschied war, dass ich das tokenin der dekonstruierte PrivateRoute component. Durch die Art und Weise wird das Token aus bekommen localstoragewie diese const token = localStorage.getItem("authUser");so , wenn sie nicht da ist weiß , dass ich der Benutzer nicht authentifiziert ist. Dies kann auch diesen Fehler verursachen.


0

Es ist wirklich ganz einfach. Ich habe dieses Problem bekommen, als ich angefangen habe, React zu codieren, und das Problem ist fast immer, weil der Import:

import React, { memo } from 'react';

Sie können dies zerstören, da react lib eine Eigenschaft als Memo hat, aber Sie können so etwas nicht zerstören

import { user } from 'assets/images/icons/Profile.svg';

weil es kein Objekt ist.

Ich hoffe es hilft!


0

React.Fragment

Das Problem wurde für mich behoben

Fehlercode:

 return (
            <section className={classes.itemForm}>
             <Card>
             </Card> 
            </section>
      );

Fix

 return (
      <React.Fragment>
        <section className={classes.itemForm}>
         <Card>
         </Card> 
        </section>
      </React.Fragment>
  );

0

Dies ist kein direktes Problem im Zusammenhang mit dem Import / Export. In meinem Fall habe ich ein untergeordnetes Element in einem übergeordneten Element gerendert und das untergeordnete Element verfügt über ein jsx-Element / Tag, das verwendet, aber nicht importiert wird. Ich habe es importiert und verwendet, dann wurde das Problem behoben. Das Problem lag also in jsx-Elementen, die sich im untergeordneten Element befinden, NICHT im Export des untergeordneten Elements selbst.


-1

Ich habe gerade 30 Minuten damit verbracht, dieses grundlegende Problem zu lösen.

Mein Problem war, dass ich reaktive native Elemente importierte

z.B import React, { Text, Image, Component } from 'react';

Und ich habe versucht, sie zu verwenden, was dazu führte, dass ich diesen Fehler erhielt.

Sobald ich von Schalter <Text>zu <p>und <Image>auf <img>alles funktioniert wie erwartet.


-1

Ich habe diesen Fehler erhalten und keine der Antworten war mein Fall. Es könnte jemandem helfen, zu googeln:

Ich habe einen falschen Proptyp definiert:

ids: PropTypes.array(PropTypes.string)

Es sollte sein:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode und der Kompilierungsfehler gaben mir keinen korrekten Hinweis.


-2

BEARBEITEN

Sie komplexieren den Prozess. Mach das einfach:

index.js:

import React from 'react';
import ReactDom from 'react-dom';
import routes from './routes.js';
require('jquery');
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.min.js';
import './css/main.css';

ReactDom.render(<routes />, document.getElementById('root'));

route.js:

import React from 'react';
import { AppContainer } from 'react-hot-loader';
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
import store from './store/store.js';
import { Provider } from 'react-redux';
import App from './containers/App.jsx';
import Products from './containers/shop/Products.jsx';
import Basket from './containers/shop/Basket.jsx';

const routes =
    <AppContainer>
        <Provider store={store}>
            <Router history={browserHistory}>
                <Route path="/" component={App}>
                    <IndexRoute component={Products} />
                    <Route path="/basket" component={Basket} />
                </Route>
            </Router>
        </Provider>
    </AppContainer>;

export default routes;

Sind Sie sicher, dass das Problem von hier kommt? Und nicht von den Seiten selbst?
John Smith
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.