React.createElement: typ jest nieprawidłowy - oczekiwano ciągu


112

Próbuję uzyskać responsywny router (v4.0.0) i reagujący-hot-loader (3.0.0-beta.6), aby grać ładnie, ale otrzymuję następujący błąd w konsoli przeglądarki:

Ostrzeżenie: React.createElement: type jest nieprawidłowy - oczekiwano ciągu znaków (dla komponentów wbudowanych) lub klasy / funkcji (dla komponentów złożonych), ale otrzymano: undefined. Prawdopodobnie zapomniałeś wyeksportować komponentu z pliku, w którym jest zdefiniowany.

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;

Jeśli używaszreak-router-config, upewnij się, że używasz componentwłaściwości zamiast render, ponieważ pakiet nie obsługuje późniejszego. Zobacz więcej na GitHub .
totymedli

Odpowiedzi:


146

W większości przypadków jest to spowodowane nieprawidłowym eksportem / importem.

Typowy błąd:

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

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

Możliwa opcja:

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

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

Jest kilka powodów, dla których może być źle, ale ten błąd jest spowodowany niezgodnością importu / eksportu w 60% przypadków za każdym razem.

Edytować

Zwykle powinieneś otrzymać stos, który wskazuje przybliżoną lokalizację miejsca wystąpienia błędu. Zwykle następuje to bezpośrednio po wiadomości, którą otrzymałeś w swoim pierwotnym pytaniu.

Jeśli się nie wyświetla, warto zbadać przyczynę (może to być ustawienie kompilacji, którego brakuje). Niezależnie od tego, jeśli się nie wyświetla, jedynym sposobem działania jest zawężenie w przypadku niepowodzenia eksportu / importu.

Niestety, jedynym sposobem na zrobienie tego bez śledzenia stosu jest ręczne usunięcie każdego modułu / podmodułu, dopóki nie pojawi się błąd, a następnie powrócisz do stosu.

Edytuj 2

W komentarzach rzeczywiście był to problem z importem, a konkretnie z importowaniem modułu, który nie istniał


Przyjrzeliśmy się śladowi, który wskazuje na wiersz 12 w pliku route.js. Ta linia to<IndexRoute component={Products} />
JoeTidee

2
Czy na pewno index route jest częścią RR4? (Jestem prawie pewien, że tak nie jest)
Chris

To był problem - dzięki! Wróciłem do wersji 3.0.0
JoeTidee

Świetne, dobre rzeczy. Możesz oznaczyć to jako zaakceptowaną odpowiedź, ponieważ pomoże ona przyszłym czytelnikom dowiedzieć się, jak podejść do podobnych problemów
Chris

1
@PriyaRanjanSingh Nie da się tego stwierdzić na podstawie małego komentarza. Czy możesz zadać nowe pytanie ze szczegółami?
Chris,

18

Otrzymałem również ten błąd.

Używałem:

import BrowserRouter from 'react-router-dom';

Fix robił to, zamiast tego:

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


11

Spróbuj tego

npm i react-router-dom@next

w swoim 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

Miałem ten problem, kiedy dodałem plik css do tego samego folderu, co plik komponentu.

Moje oświadczenie importowe brzmiało:

import MyComponent from '../MyComponent'

co było w porządku, gdy istniał tylko jeden plik, MyComponent.jsx. (Widziałem ten format na przykładzie i spróbowałem, a potem zapomniałem, że to zrobiłem)

Kiedy dodałem MyComponent.scss do tego samego folderu, import nie powiódł się. Może zamiast tego JavaScript załadował plik .scss, więc nie wystąpił błąd.

Mój wniosek: zawsze określaj rozszerzenie pliku, nawet jeśli jest tylko jeden plik, na wypadek, gdybyś dodał później inny.


3

Dla przyszłych pracowników Google:

Moim rozwiązaniem tego problemu była aktualizacja reacti react-domich najnowsze wersje na NPM. Najwyraźniej importowałem komponent, który używał nowej składni fragmentów i został uszkodzony w mojej starszej wersji React.


3

Tablica komponentów

Typowym sposobem uzyskania tego błędu jest użycie tablicy komponentów z indeksem pozycyjnym używanym do wybierania komponentu do renderowania z tablicy. Widziałem taki kod wiele razy:

const checkoutSteps = [Address, Shipment, Payment]

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

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Nie jest to konieczny zły kod, ale jeśli wywołasz go z niewłaściwym indeksem (np. -1Lub 3w tym przypadku), ToRenderkomponent będzie undefined, wyrzucając React.createElement: type is invalid...błąd:

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

Racjonalne rozwiązanie

Powinieneś chronić siebie i swoich kolegów przed tym trudnym do debugowania kodem, używając bardziej wyraźnego podejścia, unikając magicznych liczb i używając PropTypes:

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

Twój kod będzie wyglądał następująco:

// 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)

Korzyści z tego podejścia

  • kod jest bardziej wyraźny , możesz wyraźnie zobaczyć, co chcesz renderować
  • nie musisz pamiętać liczb i ich ukrytego znaczenia ( 1dotyczy adresu, 2 oznacza ...)
  • błędy są również wyraźne
  • bez bólu głowy dla rówieśników :)

2

Ten problem wystąpił, gdy miałem złe odniesienie w mojej instrukcji renderowania / powrotu. (wskaż nieistniejącą klasę). Sprawdź również kod instrukcji zwrotu pod kątem złych odniesień.


2

W większości przypadków oznacza to błąd importu / eksportu. Należy jednak uważać, aby nie tylko upewnić się, że plik odniesienia w śladzie stosu jest dobrze wyeksportowany, ale również, że ten plik poprawnie importuje inne komponenty . W moim przypadku błąd wyglądał tak:

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;


Dziękuję za ten komentarz! Mam ten problem od czasu aktualizacji niektórych pakietów i przewijałem wszystkie te komentarze i żaden z nich nie dotyczy tego kodu. Ale to było to - plik powodujący problem importuje coś innego, co powoduje błąd!
Diane Kaplan

2

Myślę, że najważniejszą rzeczą, o której należy pamiętać podczas rozwiązywania problemów z tym błędem, jest to, że objawia się on przy próbie utworzenia instancji składnika, który nie istnieje. Ten komponent nie musi być importowany. W moim przypadku składałem jako właściwości. Zapomniałem zaktualizować jedno z wywołań, aby poprawnie przekazać komponent po jakiejś refaktoryzacji. Niestety, ponieważ JS nie jest wpisany statycznie, mój błąd nie został przechwycony i zajęło trochę czasu, zanim zrozumiałem, co się dzieje.

Aby rozwiązać ten błąd, sprawdź komponent przed renderowaniem, aby upewnić się, że jest to typ komponentu, którego oczekujesz.


„manifestuje się, gdy próbujesz utworzyć instancję składnika, który nie istnieje” - oto co mi się przydarzyło. Komponent został importowane / eksportowane poprawnie ale mijał go jako rekwizytu przez trasie zezwolenia w reagują-router i zapomniał zmienić render={props => <Component {...props} />}się component={Component}.
displacedtexan

2

Brakowało mi fragmentu reakcji :


function Bar({ children }) {

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

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

Powyższy kod generuje powyższy błąd. Ale to rozwiązuje problem:

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

Zdarzyło mi się, gdy dodałem ReactCollapsingTable ( yarn add react-collapsing-table). Udało mi się przełączać między tym ostrzeżeniem (które spowodowało błąd nawodnienia) a <div>...</div>
``

W końcu przetransponowałem cały projekt od początku (zamiast ponownego ładowania na gorąco) i problem się powtórzył. Znalazłem rozwiązanie tutaj: stackoverflow.com/a/43969990/2821963 (zamiast import module from 'module-name'używać require(module-name).default)
superk

1

Brakowało mi tego, czego używałem

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

zamiast tego poprawna odpowiedź powinna brzmieć:

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

Oczywiście musisz dodać pakiet npm act -router-dom :

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

1

W moim przypadku zapomniałem zaimportować i wyeksportować moje (nowe) elementy wywołane przez render w pliku index.js.


0

W moim przypadku liczy się kolejność, w jakiej tworzysz komponent i renderujesz. Renderowałem komponent przed jego utworzeniem. Najlepszym sposobem jest utworzenie komponentu podrzędnego, a następnie komponentów nadrzędnych, a następnie renderowanie komponentu nadrzędnego. Zmiana kolejności rozwiązała problem.


0

W moim przypadku po prostu musiałem dokonać aktualizacji z react-router-reduxdo react-router-redux@next. Zakładam, że musiał to być jakiś problem ze zgodnością.


0

Krótko mówiąc, w jakiś sposób dzieje się co następuje:

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

Niekoniecznie musi to być związane z nieprawidłowym importem lub eksportem:

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

    return (
        <MyComponent />
    );
}

0

Jeśli masz ten błąd podczas testowania komponentu, upewnij się, że każdy komponent podrzędny renderuje się poprawnie, gdy jest uruchamiany samodzielnie, jeśli jeden z komponentów podrzędnych jest zależny od zasobów zewnętrznych do renderowania, spróbuj go wyśmiewać za pomocą żartu lub innej fałszywej biblioteki:

Przykład:

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

0

W moim przypadku błąd wystąpił podczas próby użycia ContextApi. Omyłkowo użyłem:

const MyContext = () => createContext()

Ale należało to zdefiniować jako:

const MyContext = createContext()

Umieszczam to tutaj, aby przyszli goście, którzy utkną na tak głupim błędzie, pomogli uniknąć godzin bólu głowy, ponieważ nie jest to spowodowane nieprawidłowym importem / eksportem.



0

To jest błąd, który trzeba było debugować. Jak już wielokrotnie mówiono, niewłaściwy import / eksport może spowodować ten błąd, ale zaskakująco dostałem ten błąd z małego błędu w moim przypadku react-router-dom authentication setupponiżej:

NIEPRAWIDŁOWA KONFIGURACJA:

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

PRAWIDŁOWA KONFIGURACJA:

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

Jedyną różnicą było to, że był Dekonstrukcja tokenw PrivateRoute component. Nawiasem mówiąc, token jest uzyskiwany w localstorageten const token = localStorage.getItem("authUser");sposób, więc jeśli go tam nie ma, wiem, że użytkownik nie jest uwierzytelniony. Może to również spowodować ten błąd.


0

To naprawdę proste. Mam ten problem, kiedy zacząłem kodować Reacta, a problem jest prawie zawsze, ponieważ import:

import React, { memo } from 'react';

Możesz użyć destrukturyzacji tego, ponieważ reakcja lib ma właściwość jako memo, ale nie możesz tego zrobić

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

ponieważ to nie jest przedmiot.

Mam nadzieję, że to pomoże!


0

React.Fragment

naprawił problem dla mnie

Kod błędu:

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

Naprawić

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

0

Nie jest to konieczne w przypadku bezpośredniej kwestii związanej z importem / eksportem. W moim przypadku renderowałem element podrzędny wewnątrz elementu nadrzędnego, a element podrzędny ma element / tag jsx, który jest używany, ale nie jest importowany. Zaimportowałem go i użyłem, a następnie rozwiązałem problem. Więc problem dotyczył elementów jsx, które są wewnątrz elementu podrzędnego, a NIE samego eksportu elementu potomnego.


0
xxxxx.prototype = {
  dxxxx: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

Musisz dodać // eslint-disable-line react/forbid-prop-types, to działa!


-1

Właśnie spędziłem 30 minut próbując rozwiązać ten podstawowy problem.

Mój problem polegał na tym, że importowałem reagujące elementy natywne

na przykład import React, { Text, Image, Component } from 'react';

I próbowałem ich użyć, co spowodowało, że otrzymałem ten błąd.

Kiedy przełączam się z <Text>na <p>i <Image>na <img>wszystko działało zgodnie z oczekiwaniami.


-1

Otrzymałem ten błąd i żadna z odpowiedzi nie była w moim przypadku, może to pomóc komuś w googlowaniu:

Źle zdefiniowałem Proptype:

ids: PropTypes.array(PropTypes.string)

Powinno być:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode i błąd kompilacji nie dały mi poprawnej wskazówki.


-2

EDYTOWAĆ

Kompleksujesz proces. Po prostu zrób to:

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;

Czy na pewno problem pochodzi stąd? A nie z samych stron?
John Smith
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.