React.createElement : 유형이 잘못되었습니다. 문자열이 필요합니다.


108

react-router (v4.0.0)와 react-hot-loader (3.0.0-beta.6)가 멋지게 재생되도록 시도했지만 브라우저 콘솔에서 다음 오류가 발생합니다.

경고 : React.createElement : 유형이 유효하지 않습니다. 문자열 (내장 구성 요소의 경우) 또는 클래스 / 함수 (복합 구성 요소의 경우)가 필요하지만 정의되지 않았습니다. 정의 된 파일에서 구성 요소를 내보내는 것을 잊었을 수 있습니다.

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;

당신이 사용하는 경우 반응 - 라우터 설정의 메이크업을 확인 당신이 사용하는 component대신 속성을 render패키지 나중에를 지원하지 않기 때문에. GitHub에서 자세히 알아 보세요 .
totymedli

답변:


145

대부분의 경우 이것은 잘못된 내보내기 / 가져 오기 때문입니다.

일반적인 오류 :

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

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

가능한 옵션 :

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

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

잘못 될 수있는 몇 가지 방법이 있지만 그 오류는 매번 가져 오기 / 내보내기 불일치로 인해 발생합니다.

편집하다

일반적으로 당신은 해야 실패가 발생하는 위치의 대략적인 위치를 나타내는 스택 트레이스를 얻을. 이것은 일반적으로 원래 질문에있는 메시지 바로 뒤에옵니다.

표시되지 않는 경우 이유를 조사해 볼 가치가 있습니다 (누락 된 빌드 설정일 수 있음). 그럼에도 불구하고 표시되지 않는 경우 유일한 조치는 내보내기 / 가져 오기가 실패한 위치를 좁히는 것 입니다.

슬프게도 스택 추적없이이를 수행하는 유일한 방법은 더 이상 오류가 발생하지 않을 때까지 각 모듈 / 하위 모듈을 수동으로 제거한 다음 스택을 백업하는 것입니다.

편집 2

주석을 통해 실제로 존재하지 않는 모듈을 가져 오는 것은 실제로 가져 오기 문제였습니다.


route.js의 12 행을 가리키는 추적을 살펴 보았습니다. 그 라인은<IndexRoute component={Products} />
JoeTidee

2
인덱스 경로가 실제로 RR4의 일부 라고 확신 합니까? (나는 확신이없는거야)
크리스

그게 문제였습니다-감사합니다! 나는 v3.0.0로 다시 복귀 한
JoeTidee

좋아, 좋은 물건. 그것이 미래의 리더 비슷한 문제에 접근하는 방법을 알고 도움이 될 것입니다 허용 대답으로 표시 주시기 바랍니다
크리스

1
@PriyaRanjanSingh 작은 댓글만으로는 말할 수 없습니다. 세부 사항이있는 새 질문을 게시 할 수 있습니까?
Chris

18

이 오류도 발생했습니다.

나는 사용하고 있었다 :

import BrowserRouter from 'react-router-dom';

수정은 대신 다음을 수행했습니다.

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


11

이 시도

npm i react-router-dom@next

당신의 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

구성 요소 파일과 동일한 폴더에 css 파일을 추가 할 때이 문제가 발생했습니다.

내 수입 명세서는 다음과 같습니다.

import MyComponent from '../MyComponent'

MyComponent.jsx라는 단일 파일 만 있으면 괜찮 았습니다. (예제에서이 형식을보고 시도해 본 다음 수행 한 것을 잊었습니다)

MyComponent.scss를 같은 폴더에 추가했을 때 가져 오기가 실패했습니다. JavaScript가 대신 .scss 파일을로드했기 때문에 오류가 없었을 수 있습니다.

내 결론 : 나중에 다른 파일을 추가 할 경우 파일이 하나만 있더라도 항상 파일 확장자를 지정하십시오.


3

향후 Google 사용자를 위해 :

이 문제에 대한 내 솔루션 업그레이드했다 reactreact-domNPM에 최신 버전에. 분명히 새로운 조각 구문을 사용하는 구성 요소를 가져오고 있었고 이전 버전의 React에서 손상되었습니다.


3

구성 요소 배열

이 오류를 얻는 일반적인 방법은 배열 에서 렌더링 할 구성 요소를 선택하는 데 사용되는 위치 인덱스 와 함께 구성 요소 배열을 사용하는 것 입니다. 나는 이와 같은 코드를 여러 번 보았다.

const checkoutSteps = [Address, Shipment, Payment]

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

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

잘못된 코드는 필요하지 않지만 잘못된 인덱스 (예 : -1또는 3이 경우)로 호출 하면 ToRender구성 요소가 undefined되며 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

합리적인 솔루션

보다 명시적인 접근 방식을 사용하고, 매직 넘버를 피하고 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

코드는 다음과 같습니다.

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

이 접근 방식의 이점

  • 코드가 더 명시 적 이며 렌더링하려는 내용을 명확하게 볼 수 있습니다.
  • 숫자와 숨겨진 의미 를 기억할 필요가 없습니다 ( 1주소는 2 , ...)
  • 오류는 명시 적으로 너무
  • 동료에게 두통이 없습니다 :)

2

이 문제는 render / return 문에 잘못된 참조가있을 때 발생했습니다. (존재하지 않는 클래스를 가리킴). 또한 반환 문 코드에서 잘못된 참조를 확인하십시오.


2

대부분의 경우 이는 가져 오기 / 내보내기 오류를 나타냅니다. 그러나 스택 추적에서 참조 된 파일이 잘 내보내 졌는지뿐만 아니라이 파일이 다른 구성 요소를 올바르게 가져 오는지 확인 해야합니다. 제 경우에는 오류가 다음과 같습니다.

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;


이 의견에 감사드립니다! 일부 패키지를 업데이트 한 이후로이 문제가 발생했으며 이러한 모든 주석을 스크롤 해 왔으며이 코드에서 문제가되는 것은 없습니다. 그러나 이것은 문제 파일이 오류를 일으키는 다른 것을 가져옵니다!
Diane Kaplan

2

이 버그를 해결할 때 깨달아야 할 가장 중요한 것은 존재하지 않는 구성 요소를 인스턴스화하려고 할 때 나타납니다. 이 구성 요소는 가져올 필요가 없습니다. 제 경우에는 구성 요소를 속성으로 전달했습니다. 일부 리팩토링 후 구성 요소를 제대로 전달하기 위해 호출 중 하나를 업데이트하는 것을 잊었습니다. 불행히도 JS가 정적으로 입력되지 않았기 때문에 내 버그가 잡히지 않았고 무슨 일이 일어나고 있는지 알아내는 데 시간이 걸렸습니다.

이 버그를 해결하려면 렌더링하기 전에 구성 요소를 검사하여 예상 한 구성 요소 유형인지 확인하십시오.


"존재하지 않는 구성 요소를 인스턴스화하려고 할 때 나타납니다."이것이 저에게 일어난 일입니다. 구성 요소가 올바르게 수출 / 수입했지만, 난이의 인증 경로를 통해 소품으로 통과되었다 라우터를 반응하여 변경하는 것을 잊었다 render={props => <Component {...props} />}component={Component}.
displacedtexan

2

React Fragment 가 누락되었습니다 .


function Bar({ children }) {

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

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

위의 코드는 위의 오류를 발생시킵니다. 그러나 이것은 그것을 수정합니다.

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

ReactCollapsingTable ( yarn add react-collapsing-table)을 추가했을 때 나에게 일어났습니다 . 나는 (수화 오류가 발생 있음)이 경고를 교대로 관리하고, 컴파일 된 내부에서 발견 된 그 '창은 정의되지 않은'반응-테이블 붕괴 모듈을 ... 심지어 포장을 함께 <div>...</div>하지 도움을 더 이상 수행
superk

결국 나는 처음부터 (핫 리로드 대신) 전체 프로젝트를 다시 변환했고 문제가 다시 발생했습니다. 여기에서 해결책을 찾았습니다. stackoverflow.com/a/43969990/2821963 (대신 import module from 'module-name', 사용 require(module-name).default)
superk

1

나를 위해 놓친 것은 내가 사용하고 있었다

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

대신 또는 정답은 다음과 같아야합니다.

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

물론 npm 패키지 react-router-dom 을 추가해야합니다 .

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

1

제 경우에는 index.js 파일에서 렌더링에 의해 호출되는 (새) 요소를 가져오고 내보내는 것을 잊었습니다.


0

제 경우에는 구성 요소를 만들고 렌더링하는 순서가 중요했습니다. 구성 요소를 만들기 전에 렌더링했습니다. 가장 좋은 방법은 자식 구성 요소를 만든 다음 부모 구성 요소를 만든 다음 부모 구성 요소를 렌더링하는 것입니다. 주문을 변경하면 문제가 해결되었습니다.


0

제 경우에는 그냥 업그레이드했다 react-router-reduxreact-router-redux@next. 나는 그것이 일종의 호환성 문제라고 가정하고 있습니다.


0

간단히 말해서, 어떻게 든 다음과 같은 일이 발생합니다.

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

잘못된 가져 오기 또는 내보내기와 반드시 관련이있는 것은 아닙니다.

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

    return (
        <MyComponent />
    );
}

0

구성 요소를 테스트 할 때이 오류가 발생하면 모든 자식 구성 요소가 단독으로 실행될 때 올바르게 렌더링되는지 확인하고, 자식 구성 요소 중 하나가 렌더링 할 외부 리소스에 의존하는 경우 jest 또는 다른 모의 lib를 사용하여 조롱 해보십시오.

예 :

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

0

제 경우에는 ContextApi를 사용하려고 할 때 오류가 발생했습니다. 실수로 다음을 사용했습니다.

const MyContext = () => createContext()

그러나 다음과 같이 정의되어야합니다.

const MyContext = createContext()

나는 그런 어리석은 실수에 갇힌 미래의 방문자가 두통을 피하는 데 도움이 될 수 있도록 여기에 게시하고 있습니다. 이것은 잘못된 수입 / 수출로 인한 것이 아니기 때문입니다.



0

이것은 디버깅 방법에 대한 오류입니다. 여러 번 말했듯이 부적절한 가져 오기 / 내보내기로 인해이 오류가 발생할 수 있지만 놀랍게도 내 작은 버그로 인해이 오류가 발생했습니다.react-router-dom authentication setup 아래 .

잘못된 설정 :

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

올바른 설정 :

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

유일한 차이점은 나는를 해체이었다 tokenPrivateRoute component. 그건 그렇고 토큰은 localstorage이와 같이 얻었 const token = localStorage.getItem("authUser");으므로 토큰이 없으면 사용자가 인증되지 않았 음을 압니다. 이로 인해 해당 오류가 발생할 수도 있습니다.


0

정말 간단합니다. React 코딩을 시작할 때이 문제가 발생했으며 거의 ​​항상 가져 오기 때문에 문제가 발생합니다.

import React, { memo } from 'react';

react lib에는 메모로 속성이 있기 때문에 destructuring을 사용할 수 있지만 이와 같은 destructuring을 할 수는 없습니다

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

객체가 아니기 때문입니다.

도움이 되었기를 바랍니다.


0

React.Fragment

나를 위해 문제를 해결했습니다.

에러 코드:

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

고치다

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

0

이것은 수입 / 수출과 관련된 직접적인 문제가 아닙니다. 제 경우에는 부모 요소 안에 자식 요소를 렌더링하고 있었고 자식 요소에는 사용되지만 가져 오지 않은 jsx 요소 / 태그가 있습니다. 나는 그것을 수입하고 그것을 사용한 다음 문제를 해결했습니다. 따라서 문제는 자식 요소 자체의 내보내기가 아닌 자식 요소 내부에있는 jsx 요소에있었습니다.


0

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

을 추가해야 // eslint-disable-line react/forbid-prop-types작동합니다!


-1

이 BASIC 기본 문제를 해결하는 데 30 분을 보냈습니다.

내 문제는 내가 반응 네이티브 요소를 가져오고 있었다는 것입니다.

예 : import React, { Text, Image, Component } from 'react';

그리고 그것들을 사용하려고하면이 오류가 발생했습니다.

내가 전환하면 <Text><p><Image><img>모든으로 예상했다.


-1

이 오류가 발생하고 응답이 내 경우가 아니므로 누군가 인터넷 검색에 도움이 될 수 있습니다.

Proptype을 잘못 정의했습니다.

ids: PropTypes.array(PropTypes.string)

그것은해야한다:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode 및 컴파일 오류로 인해 올바른 힌트가 제공되지 않았습니다.


-2

편집하다

당신은 과정을 복잡하게 만들고 있습니다. 다음을 수행하십시오.

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;

문제가 여기에서 오는 것이 확실합니까? 그리고 페이지 자체가 아니라?
존 스미스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.