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

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;



답변

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

일반적인 오류 :

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

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


답변

이 오류도 발생했습니다.

나는 사용하고 있었다 :

import BrowserRouter from 'react-router-dom';

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

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


답변

이 시도

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;


답변

named export및을 알고 있어야 default export합니다. ES6 가져 오기에 언제 중괄호를 사용해야합니까?를 참조하십시오 .

제 경우에는

import Provider from 'react-redux'

…에

import { Provider } from 'react-redux'


답변

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

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

import MyComponent from '../MyComponent'

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

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

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


답변

향후 Google 사용자를 위해 :

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


답변

구성 요소 배열

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

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 , …)
  • 오류는 명시 적으로 너무
  • 동료에게 두통이 없습니다 🙂