React.createElement: tür geçersiz - bir dize bekleniyordu


114

Güzelce oynamak için react-router (v4.0.0) ve react-hot-loader (3.0.0-beta.6) almaya çalışıyorum, ancak tarayıcı konsolunda aşağıdaki hatayı alıyorum:

Uyarı: React.createElement: type geçersiz - bir dize (yerleşik bileşenler için) veya bir sınıf / işlev (bileşik bileşenler için) bekleniyordu ancak var: tanımsız. Bileşeninizi, içinde tanımlandığı dosyadan dışa aktarmayı unutmuş olabilirsiniz.

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;

Eğer kullanırsanız tepki-yönlendirici-config marka emin kullanmak componentyerine özelliğini renderpaketi sonradan desteklemediği için. GitHub'da daha fazlasını görün .
totymedli

Yanıtlar:


148

Çoğu zaman bunun nedeni yanlış bir ihracat / ithalattır.

Yaygın hata:

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

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

Olası seçenek:

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

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

Yanlış olmasının birkaç yolu vardır, ancak bu hata her seferinde% 60 oranında ithalat / ihracat uyumsuzluğundan kaynaklanmaktadır.

Düzenle

Tipik olarak , hatanın meydana geldiği yaklaşık konumu gösteren bir yığın izleme almalısınız . Bu, genellikle orijinal sorunuzdaki mesajın hemen ardından gelir.

Gösterilmezse, nedenini araştırmaya değer olabilir (eksik olduğunuz bir yapı ayarı olabilir). Her şeye rağmen, görünmüyorsa, yapılacak tek işlem, dışa / içe aktarmanın başarısız olduğu yeri daraltmaktır .

Ne yazık ki, bunu yığın izleme olmadan yapmanın tek yolu, artık hatayı almayana kadar her modülü / alt modülü manuel olarak kaldırmak ve ardından yığını yedeklemek için çalışmaktır.

Düzenle 2

Yorumlar aracılığıyla, özellikle var olmayan bir modülü içe aktarmak gerçekten bir içe aktarma sorunuydu


Route.js'nin 12. satırına işaret eden ize baktım. Bu satır<IndexRoute component={Products} />
JoeTidee

2
Dizin yolunun aslında RR4'ün bir parçası olduğundan emin misiniz ? (Öyle olmadığından oldukça eminim)
Chris

Sorun buydu - teşekkürler! V3.0.0'a geri döndüm
JoeTidee

Harika, güzel şeyler. Gelecekteki okuyucuların benzer sorunlara nasıl yaklaşacaklarını bilmelerine yardımcı olacağından, bunu kabul edilen yanıt olarak işaretlemekten çekinmeyin
Chris

1
@PriyaRanjanSingh Küçük bir yorumdan söylemek imkansız. Ayrıntıları olan yeni bir soru gönderebilir misin?
Chris

18

Ben de bu hatayı alıyordum.

Ben kullanıyordum:

import BrowserRouter from 'react-router-dom';

Fix bunu yapıyordu, bunun yerine:

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


11

Bunu dene

npm i react-router-dom@next

senin içinde 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

Bileşen dosyasıyla aynı klasöre bir css dosyası eklediğimde bu sorunu yaşadım.

İthalat beyannamem şuydu:

import MyComponent from '../MyComponent'

sadece tek bir dosya olan MyComponent.jsx varken bu iyiydi. (Bu formatı bir örnekte gördüm ve denedim, sonra yaptığımı unuttum)

MyComponent.scss'i aynı klasöre eklediğimde, içe aktarma başarısız oldu. Belki JavaScript bunun yerine .scss dosyasını yükledi ve bu nedenle hata olmadı.

Vardığım sonuç: Daha sonra başka bir dosya eklemeniz durumunda, yalnızca bir dosya olsa bile dosya uzantısını her zaman belirtin.


3

Gelecekteki Google çalışanları için:

Bu soruna çözümüm , NPM'de yükseltmek reactve react-domen son sürümlerine geçmek oldu . Görünüşe göre yeni parça sözdizimini kullanan bir Bileşeni içe aktarıyordum ve eski React sürümümde bozulmuştu.


3

Bileşen dizisi

Bu hatayı almanın yaygın bir yolu, diziden oluşturulacak bileşeni seçmek için kullanılan konumsal bir dizine sahip bir bileşen dizisi kullanmaktır. Bunun gibi bir kodu birçok kez gördüm:

const checkoutSteps = [Address, Shipment, Payment]

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

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

Bu gerekli kötü kod değildir, ancak onu yanlış bir indeksle çağırırsanız (örneğin -1, 3bu durumda), ToRenderbileşen şu hatayı undefinedatar React.createElement: type is invalid...:

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

Akılcı bir çözüm

Sen gerektiğini korumak Kendinizi ve bu sizin Meslektaşlarımız zor-debug , daha açık bir yaklaşım kullanarak sihirli numaralar kaçınarak ve PropTypes kullanarak kod:

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

Ve kodunuz şöyle görünecek:

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

Bu yaklaşımın faydaları

  • kod daha açık , ne oluşturmak istediğinizi açıkça görebilirsiniz
  • sayıları ve gizli anlamlarını hatırlamanıza gerek yok ( 1Adres içindir, 2 ... içindir)
  • hatalardır açık çok
  • akranlarınız için baş ağrısı yok :)

2

Bu sorun, render / return ifademde kötü bir referans olduğunda başıma geldi. (mevcut olmayan bir sınıfı işaret edin). Ayrıca hatalı referanslar için dönüş ifade kodunuzu kontrol edin.


2

Çoğu zaman bu bir içe / dışa aktarma hatasını gösterir. Ancak yığın izlemede referans verilen dosyanın kendi kendine iyi bir şekilde dışa aktarıldığından değil, aynı zamanda bu dosyanın diğer bileşenleri doğru şekilde içe aktardığından da emin olun. Benim durumumda hata şöyleydi:

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;


Bu yorumunuz için teşekkürler! Bazı paketleri güncellediğimden beri bu sorunu yaşıyorum ve tüm bu yorumları gözden geçiriyorum ve hiçbiri bu kodda sorunlu değil. Ama bu buydu - sorunlu dosya, hataya neden olan başka bir şeyi içe aktarıyor!
Diane Kaplan

2

Bence bu hatayı giderirken farkına varılması gereken en önemli şey, var olmayan bir bileşeni başlatmaya çalıştığınızda ortaya çıkmasıdır. Bu bileşenin içe aktarılmasına gerek yoktur. Benim durumumda bileşenleri özellik olarak geçiriyordum. Bazı yeniden düzenlemelerden sonra, çağrılardan birini bileşeni düzgün bir şekilde geçirmek için güncellemeyi unuttum. Ne yazık ki, JS statik olarak yazılmadığından, hatam yakalanmadı ve ne olduğunu anlamak biraz zaman aldı.

Bu hatayı gidermek için, bileşeni oluşturmadan önce inceleyin, beklediğiniz bileşen türü olduğundan emin olun.


"var olmayan bir bileşeni somutlaştırmaya çalıştığınızda ortaya çıkıyor" - bana olan buydu. Bileşen doğru bir şekilde verilen / ama içinde bir yetki yol aracılığıyla bir destek olarak da geçiyordu-yönlendirici reaksiyona ve değiştirmek için unuttum render={props => <Component {...props} />}için component={Component}.
displacedtexan

2

Bir React Parçası eksikti :


function Bar({ children }) {

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

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

Yukarıdaki kod, yukarıdaki hatayı atar. Ancak bu sorunu düzeltir:

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

ReactCollapsingTable ( yarn add react-collapsing-table) eklediğimde başıma geldi . Bu uyarı (bir hidrasyon hatasıyla sonuçlanan) ile derlenmiş tepki çökme tablosu modülünün içinde algılanan bir 'pencere tanımlanmadı' arasında <div>...</div>
geçiş yapmayı başardım ... Sarmak

Sonunda tüm projeyi baştan (çalışırken yeniden yükleme yerine) yeniden aktardım ve sorun tekrarlandı. Çözümü burada import module from 'module-name'require(module-name).default
buldum

1

Benim için eksik olan şey kullanıyordum

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

bunun yerine veya doğru cevap şöyle olmalıdır:

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

Elbette npm paketi react-router-dom eklemeniz gerekir :

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

1

Benim durumumda, index.js dosyasındaki render tarafından çağrılan (yeni) öğelerimi içe ve dışa aktarmayı unuttum.


0

Benim durumumda, bileşeni yarattığınız ve oluşturduğunuz sıra önemliydi. Oluşturmadan önce bileşeni işliyordum. En iyi yol, alt bileşeni ve ardından üst bileşenleri oluşturmak ve ardından üst bileşeni oluşturmaktır. Sırayı değiştirmek sorunu benim için çözdü.


0

Benim durumumda sadece sürümünden yükseltmem react-router-reduxgerekiyordu react-router-redux@next. Bunun bir çeşit uyumluluk sorunu olduğunu varsayıyorum.


0

Basitçe söylemek gerekirse, bir şekilde aşağıdakiler oluyor:

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

Bazı yanlış ithalat veya ihracat ile ilgili olmayabilir:

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

    return (
        <MyComponent />
    );
}

0

Bir bileşeni test ederken bu hatayı yaşıyorsanız, her alt bileşenin tek başına çalıştırıldığında doğru şekilde oluşturulduğundan emin olun, alt bileşeninizden biri oluşturmak için harici kaynaklara bağlıysa, jest veya başka bir alaycı lib ile alay etmeyi deneyin:

Örnek:

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

0

Benim durumumda, ContextApi'yi kullanmaya çalışırken hata oluştu. Yanlışlıkla kullandım:

const MyContext = () => createContext()

Ancak şu şekilde tanımlanmalıydı:

const MyContext = createContext()

Bu kadar aptalca bir hataya takılan gelecekteki ziyaretçilerin saatlerce baş ağrısını önlemek için yardımcı olması için bunu buraya gönderiyorum, çünkü bu yanlış ithalat / ihracattan kaynaklanmıyor.


0

Döngüsel bağımlılık da bunun nedenlerinden biridir. [Genel olarak]


0

Bu, nasıl hata ayıklanması gereken bir hatadır. Birçok kez söylendiği gibi, uygun olmayan içe / dışa aktarma bu hataya neden olabilir, ancak şaşırtıcı bir şekilde bu hatayı react-router-dom authentication setupaşağıdaki durumumdaki küçük bir hatadan aldım:

YANLIŞ KURULUM:

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

DOĞRU KURULUM:

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

Tek fark yapısökümünden oldu tokeniçinde PrivateRoute component. Bu arada, belirteç localstoragebu const token = localStorage.getItem("authUser");şekilde elde edildiğinden, orada değilse kullanıcının kimliğinin doğrulanmadığını biliyorum. Bu aynı zamanda bu hataya da neden olabilir.


0

Gerçekten çok basit. React'i kodlamaya başladığımda bu sorunu yaşadım ve sorun neredeyse her zaman içe aktarım:

import React, { memo } from 'react';

Bunu yok etmeyi kullanabilirsiniz çünkü react lib not olarak bir özelliğe sahiptir, ancak böyle bir şeyi yok edemezsiniz

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

çünkü bu bir nesne değil.

Umarım yardımcı olur!


0

React.Fragment

benim için sorunu çözdü

Hata kodu:

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

Düzelt

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

0

Bu ithalat / ihracat ile ilgili doğrudan bir mesele gerekli değildir. Benim durumumda, bir üst öğe içinde bir alt öğe oluşturuyordum ve alt öğe, kullanılan ancak içe aktarılmayan jsx öğesi / etiketine sahip. Ben ithal ettim ve kullandım sonra sorunu düzeltti. Dolayısıyla sorun, alt öğenin kendisinin dışa aktarılması DEĞİL, alt öğenin içinde bulunan jsx öğelerindeydi.


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

Eklemelisin // eslint-disable-line react/forbid-prop-types, sonra işe yarıyor!


0

Tam olarak aynı hatayı aldım, bunun yerine şunu yapın:

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

1
Web paketinizi izlemeye yeniden başlamayı unutmayın
Tong Yu

0

İthalatınızın / ihracatınızın yanlış olduğu anlamına gelir .

  • Yeni eklenenleri kontrol edin import/exports.
  • Benim durumumda gereksiz parantez kullanıyordum. Bu küme parantezlerini kaldırdığımda sorun otomatik olarak çözüldü.
import { OverlayTrigger } from 'react-bootstrap/OverlayTrigger';

-1

Bu BASIC temel sorunu çözmeye çalışmak için 30 dakika harcadım.

Benim sorunum, yerel react elementlerini

Örneğin import React, { Text, Image, Component } from 'react';

Ve onları kullanmaya çalışmak bu hatayı almama neden oldu.

Ben diğerine geçiş yaptığınızda <Text>için <p>ve <Image>karşı <img>her şey beklendiği gibi çalıştı.


-1

Bu hatayı alıyordum ve yanıtların hiçbiri benim durumum değildi, birisinin googling yapmasına yardımcı olabilir:

Bir Proptype'ı yanlış tanımlıyordum:

ids: PropTypes.array(PropTypes.string)

Olmalı:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode ve derleme hatası bana doğru bir ipucu vermedi.


-2

DÜZENLE

Süreci karmaşıklaştırıyorsunuz. Sadece şunu yap:

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;

Sorunun buradan geldiğine emin misin? Ve sayfaların kendisinden değil mi?
John Smith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.