Programing

React.createElement: 유형이 잘못됨 - 문자열 필요

c10106 2022. 3. 11. 22:17
반응형

React.createElement: 유형이 잘못됨 - 문자열 필요

리액트-라우터(3.0.0-베타.6)와 리액트-핫-로더(3.0.0-베타.6)가 잘 작동하도록 시도하지만 브라우저 콘솔에서 다음 오류가 표시됨:

Warning: React.createElement: type is invalid -- expected a string
(for built-in components) or a class/function (for composite
components) but got: undefined. You likely forgot to export your
component from the file it's defined in.

인덱스.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() );

routes.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';

틀릴 수 있는 몇 가지 방법이 있지만, 그 오류는 수출입이 매번 60%씩 불일치하기 때문이다.

편집

일반적으로 고장 발생 지점의 대략적인 위치를 나타내는 스택 트레이스를 구해야 한다.이것은 일반적으로 당신이 처음 질문에서 가지고 있는 메시지 바로 뒤에 따른다.

표시되지 않으면 그 이유를 조사할 가치가 있을 수 있다(누락한 빌드 설정일 수 있음).그럼에도 불구하고, 만약 그것이 나타나지 않는다면, 수출입이 실패하는 에서 유일한 행동경로는 좁혀지고 있는 것이다.

안타깝게도 스택 트레이스가 없는 유일한 방법은 더 이상 오류가 발생하지 않을 때까지 각 모듈/하위 모듈을 수동으로 제거한 다음 스택을 다시 백업하는 것이다.

편집 2

코멘트를 통해, 그것은 정말로 수입 문제였고, 특히 존재하지 않는 모듈을 수입했다.

나도 이런 실수를 하고 있었어.

사용 중:

import BrowserRouter from 'react-router-dom';

픽스는 대신 이렇게 하고 있었다.

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

이것을 사용해 보십시오.

npm i react-router-dom@next

당신의 앱.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;

구성 요소 배열

이 오류를 얻는 일반적인 방법은 배열에서 렌더링할 구성요소를 선택하는 데 사용되는 위치 인덱스와 함께 구성요소 배열을 사용하는 것이다.이런 암호를 여러 번 봤어

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는 ...용)
  • 오류도 명백하다.
  • 또래에게는 두통 없음 :)

알아둘 필요가 있다.named export그리고default export참고 항목 ES6 수입 컬브 브레이스를 사용해야 하는 경우?

나의 경우, 나는 다른 사람과 바꿔서 고쳤다.

import Provider from 'react-redux'

import { Provider } from 'react-redux'

css 파일을 컴포넌트 파일과 같은 폴더에 추가했을 때 이런 문제가 있었다.

나의 수입명세서는 다음과 같다.

import MyComponent from '../MyComponent'

파일이 하나뿐일 때 괜찮았던 것. MyComponent.jsx. (이 형식을 예시로 보고 시도했다가 잊어버렸다)

MyComponent.scss를 동일한 폴더에 추가했을 때 가져오기가 실패함자바스크립트가 .scss 파일을 대신 로드했기 때문에 오류가 없었던 것 같다.

제 결론은 나중에 다른 파일을 추가할 경우를 대비하여 항상 파일 확장명을 지정하십시오.

나도 이런 실수를 하고 있었어.

사용 중:

import ReactDOM from 'react-dom';

픽스는 대신 이렇게 하고 있었다.

import {ReactDOM} from 'react-dom';

미래의 구글러인 경우:

이 문제에 대한 나의 해결책은 업그레이드하는 것이었다.react그리고react-domNPM의 최신 버전으로.분명히 나는 새로운 단편 구문을 사용하는 컴포넌트를 가져오는 중이었는데, 그것은 나의 이전 버전의 리액션에서 깨졌다.

이 문제는 내가 렌더링/반품 명세서에서 잘못된 참조를 했을 때 일어났다.(존재하지 않는 클래스를 가리킴).또한 반송 명세서 코드에서 불량 참조가 있는지 확인하십시오.

대부분의 경우 이는 수출입 오류를 나타낸다.그러나 스택 추적에서 참조된 파일이 자체로 잘 내보내지는 것은 물론 이 파일이 다른 구성 요소를 올바르게 가져오고 있는지 확인하십시오.나의 경우 오류는 다음과 같았다.

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;

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

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

그것은 당신의 수출입이 잘못되었다는 것을 의미한다.

  • 신규추가조회import/exports.
  • 내 경우는 불필요한 곱슬 괄호를 사용하고 있었다.이 곱슬 괄호를 제거했더니 문제가 자동으로 해결되었어.
import { OverlayTrigger } from 'react-bootstrap/OverlayTrigger';

경우 VS코드는 나를 실망시켰다.

다음은 내 구성 요소의 계층:

<HomeScreen> =>  <ProductItemComponent> =>  <BadgeProductComponent>

ProductItemComponent를 잘못 수입했다.사실은 이 구성요소가 예전에는 공유 폴더에 있었지만, 그 다음에는 홈 폴더로 옮겨졌다는 것이다.그러나 파일을 다른 폴더로 이동해도 가져오기가 업데이트되지 않고그대로 유지됨:

../shared/components

동시에 부품은 잘 작동했고 VS 코드는 오류를 강조하지 않았다.그러나 ProductItemComponent에 새로운 BadgeProductComponent를 추가했을 때 렌더 오류가 발생하여 문제가 새로운 BadgeProductComponent에 있다고 생각하였는데, 이 구성 요소를 제거하면 모든 것이 작동되기 때문이다!

게다가, 만약 내가 ../공유/구성 요소 주소가 있는 ProductItemComponent로 핫키를 통과한다면, VS Code는 나를 주소와 함께 홈 폴더로 리디렉션했다./home/snews.

일반적으로 모든 구성 요소 수준에서 모든 가져오기의 정확성을 점검하십시오.

리액션 파편을 놓치고 있었다.


function Bar({ children }) {

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

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

위의 코드는 위의 오류를 발생시킨다.그러나 이를 통해 다음과 같은 문제를 해결할 수 있다.

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

나의 경우는 위에서 말한 많은 대답들처럼 수입 문제가 아니었다.내 것에서는 포장지 구성요소를 사용해서 번역 논리를 폈고, 나는 아동 구성요소를 그렇게 잘못 전달하고 있었다.

const WrappedComponent = I18nWrapper(<ChildForm {...additionalProps} />);

함수로 전달했어야 하는 경우:

const WrappedComponent = I18nWrapper(() => <ChildForm {...additionalProps} />);

내가 놓친 것은 내가 사용했다는 것이다.

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

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

예:

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

내 경우 ContextApi를 사용하려고 할 때 오류가 발생했어.내가 잘못 사용한 것은 다음과 같다.

const MyContext = () => createContext()

그러나 그것은 다음과 같이 정의되어야 했다.

const MyContext = createContext()

이런 어리석은 실수를 저지르는 미래의 방문객들이 몇 시간 동안 두통을 피할 수 있도록 하기 위해 여기에 게시하는 것인데, 이것은 잘못된 수출입으로 인한 것이 아니기 때문이다.

순환 종속도 그 이유 중 하나이다.[일반적으로]

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

꽤 간단해, 정말로.내가 리액션을 시작했을 때 이 문제가 발생했는데, 문제는 거의 항상 가져오기 때문이다.

import React, { memo } from 'react';

react lib에는 메모로서 속성이 있기 때문에 이것을 파괴할 수 있지만, 이와 같은 것을 파괴할 수는 없다.

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

왜냐면 그건 물건이 아니니까.

도움이 되길 바래!

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

추가해야 함// eslint-disable-line react/forbid-prop-types그럼 효과가 있군!

작업 중인 응용 프로그램에서 대응 구성 요소의 이름을 브라우저 저장소에 위젯 구성으로 저장한 경우.이러한 구성 요소 중 일부는 삭제되었고 앱은 여전히 렌더링을 시도하고 있었다.브라우저 캐시를 지움으로써 문제를 해결할 수 있었다.

나는 이름이 같지만 확장명이 다른 두 개의 파일을 가지고 있었다.그래서 나는 수입에 연장을 명시해야 했다.

제거하기 위해Switch문제를 해결하다

import React from "react";
import "./styles.css";
import { Route, BrowserRouter, Routes } from "react-router-dom";
import LoginPage from "./pages/LoginPage";
import HomePage from "./pages/HomePage";

export default function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route exact path="/" element={<HomePage />} />
        <Route path="/login" element={<LoginPage />} />
      </Routes>
    </BrowserRouter>
  );
}

내 경우 구성요소를 작성하고 렌더링하는 순서가 중요했다.구성 요소를 생성하기 전에 렌더링 중이었습니다.가장 좋은 방법은 자식 구성 요소를 만든 다음 부모 구성 요소를 렌더링하는 것이다.순서를 바꿔서 문제가 해결되었다.

내 경우에는 업그레이드만 하면 되었다.react-router-reduxreact-router-redux@next호환성에 문제가 있었을 거라고 생각해

간단히 말해, 어쩐지 다음과 같은 일이 일어나고 있다.

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

일부 잘못된 수출입과 반드시 관련이 있는 것은 아닐 수 있다.

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

    return (
        <MyComponent />
    );
}

이것은 디버깅해야 할 몇 가지 오류다.여러 번 말했듯이, 부적절한 수출입은 이런 오류를 일으킬 수 있지만 놀랍게도 나는 작은 버그에서 이런 오류를 얻었다.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" }} />)}
    />
);

유일한 차이점은 내가 그 건물을 해체하고 있다는 것이었다.token에서PrivateRoute component그런데 그 토큰은 으로부터 얻어진다.localstorage이것처럼.const token = localStorage.getItem("authUser");그래서 만약 그것이 없다면 나는 사용자가 인증되지 않았다는 것을 안다.이것은 또한 그러한 오류를 일으킬 수 있다.

반응.파쇄

나를 위해 그 문제를 해결했다.

오류 코드:

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

고치다

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

참조URL: https://stackoverflow.com/questions/42813342/react-createelement-type-is-invalid-expected-a-string

반응형