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-dom
NPM의 최신 버전으로.분명히 나는 새로운 단편 구문을 사용하는 컴포넌트를 가져오는 중이었는데, 그것은 나의 이전 버전의 리액션에서 깨졌다.
이 문제는 내가 렌더링/반품 명세서에서 잘못된 참조를 했을 때 일어났다.(존재하지 않는 클래스를 가리킴).또한 반송 명세서 코드에서 불량 참조가 있는지 확인하십시오.
대부분의 경우 이는 수출입 오류를 나타낸다.그러나 스택 추적에서 참조된 파일이 자체로 잘 내보내지는 것은 물론 이 파일이 다른 구성 요소를 올바르게 가져오고 있는지 확인하십시오.나의 경우 오류는 다음과 같았다.
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-redux
로react-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
'Programing' 카테고리의 다른 글
동일한 페이지에 여러 번 표시된 Vuejs 구성 요소를 동기화할 수 있는가? (0) | 2022.03.12 |
---|---|
여러 키를 구별할 때까지 KeyChanged와 비교하는 방법? (0) | 2022.03.11 |
Vue 구성 요소: 라우터 링크 또는 href 속성을 동적으로 사용 (0) | 2022.03.11 |
전자 리액트렉스.양식 창의 상태 업데이트가 기본 창에 반영되지 않음 (0) | 2022.03.11 |
작업 큐:작업 오류: 정의되지 않은 것은 개체가 아니다(평가 '_the.view)._component.measureInWindow') reactive native (0) | 2022.03.11 |