反应。类型无效——期望为字符串

尝试得到react-router (v4.0.0)和react-hot loader (3.0.0-beta.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.

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() );

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;
600841 次浏览

编辑

你把过程复杂化了。只要这样做:

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'));

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

有几种方法可能是错误的,但这种错误是由于导入/导出不匹配造成的,每次都是如此。< br >

编辑

通常你应该会得到一个stacktrace,它指示了故障发生的大致位置。这通常跟在你最初问题的信息之后。

如果没有显示,可能需要调查原因(可能是您遗漏了一个构建设置)。无论如何,如果它没有显示,唯一的行动方针是缩小在哪里导出/导入失败。

遗憾的是,在没有stacktrace的情况下,唯一的方法是手动删除每个模块/子模块,直到您不再得到错误,然后再从堆栈中返回。

编辑2

通过注释,这确实是一个导入问题,特别是导入一个不存在的模块

试试这个

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;

我所缺少的是我正在使用

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

我也得到了这个错误。

我用的是:

import BrowserRouter from 'react-router-dom';

费克斯是这样做的:

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

当我将css文件添加到与组件文件相同的文件夹时,我遇到了这个问题。

我的重要陈述是:

import MyComponent from '../MyComponent'

当只有一个文件MyComponent.jsx时,这很好。(我在一个例子中看到了这种格式,并尝试了一下,然后忘记了我已经做到了)

当我添加MyComponent时。将SCSS导入到同一文件夹,则导入失败。也许JavaScript反而加载了.scss文件,所以没有出现错误。

我的结论是:即使只有一个文件,也要指定文件扩展名,以防稍后添加另一个文件。

对于未来的谷歌人:

我对这个问题的解决方案是将reactreact-dom升级到NPM上的最新版本。显然,我正在导入一个正在使用新的片段语法的组件,它在我的旧版本的React中被破坏了。

你需要知道named exportdefault export。看到什么时候我应该用大括号导入ES6 ?

在我的例子中,我通过改变

import Provider from 'react-redux'

import { Provider } from 'react-redux'

在我的例子中,创建组件和渲染的顺序很重要。我在创建组件之前渲染了它。最好的方法是创建子组件,然后是父组件,然后呈现父组件。改变顺序为我解决了这个问题。

在我的情况下,我只需要从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 />
);
}

我刚刚花了30分钟来解决这个基本的问题。

我的问题是我导入react原生元素

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

并试图使用它们,这导致我收到这个错误。

一旦我从<Text>切换到<p>,从<Image>切换到<img>,一切都按预期工作。

当我在我的渲染/返回语句中有一个糟糕的引用时,这个问题已经发生在我身上。(指向不存在的类)。

我得到了这个错误,没有一个响应是我的情况下,这可能会帮助一些人谷歌:

我定义了一个错误的Proptype:

ids: PropTypes.array(PropTypes.string)

它应该是:

ids: PropTypes.arrayOf(PropTypes.string)

VSCode和编译错误没有给我一个正确的提示。

如果在测试组件时出现此错误,请确保每个子组件在单独运行时都能正确呈现,如果其中一个子组件依赖于外部资源来呈现,请尝试使用jest或任何其他mock库来模拟它:

为例:

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

大多数情况下,这表示导入/导出错误。但是要注意,不仅要确保堆栈跟踪中引用的文件本身被很好地导出,还要确保这个文件正确地导入了其他组件。在我的例子中,错误是这样的:

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;

在我的例子中,错误发生在试图使用ContextApi时。我错误地使用了:

const MyContext = () => createContext()

但它应该被定义为:

const MyContext = createContext()

我把它贴在这里,以便未来的访客谁被困在这样一个愚蠢的错误将得到帮助,以避免几个小时的头痛,因为这不是由不正确的导入/导出引起的。

我认为在排除这个错误时最重要的一点是,当您试图实例化一个不存在的组件时,它就会显现出来。这个组件不需要导入。在我的例子中,我将组件作为属性传递。我忘记更新其中一个调用,以便在一些重构之后正确地传递组件。不幸的是,由于JS不是静态类型的,我的错误没有被发现,它花了一些时间来弄清楚发生了什么。

要排除此错误,在呈现组件之前检查该组件,以确保它是您所期望的组件类型。

循环依赖也是原因之一。(一般)

我漏了一个反应片段:


function Bar({ children }) {


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


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

上面的代码抛出上面的错误。但这就解决了问题:

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

在我的情况下,我忘记导入和导出我的(新)元素在index.js文件的渲染调用。

这是一个在某种程度上必须调试的错误。正如已经说过很多次,不适当的导入/导出会导致这个错误,但令人惊讶的是,我从我的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" }} />)}
/>
);

唯一的区别是我在PrivateRoute component中解构了token。顺便说一下,令牌是从localstorage中获得的,就像这个const token = localStorage.getItem("authUser");,所以如果它不在那里,我知道用户没有经过身份验证。这也会导致错误。

这真的很简单。当我开始编写React时,我遇到了这个问题,这个问题几乎总是因为导入:

import React, { memo } from 'react';

你可以对它进行解构,因为react lib有一个memo属性,但你不能这样解构

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

因为它不是一个对象。

希望能有所帮助!

反应。片段

为我修正了这个问题

错误代码:

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

修复

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

这并不是一个与进出口直接相关的问题。在我的例子中,我是在父元素中呈现子元素,并且子元素有jsx element / tag,它被使用但没有导入。我导入并使用它,然后它解决了这个问题。所以问题是在jsx元素里面的子元素,而不是导出子元素本身。

组件数组

获得此错误的常见方法是使用组件数组,并使用位置索引从数组中选择要呈现的组件。我多次看到这样的代码:

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

合理的解决方案

你应该从这个一些难以调试的代码中使用更明确的方法< em > < / em >保护你自己和你的同事,避免神奇的数字并使用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是…)
  • 错误也是显式的
  • 不会让你的同事头疼:)
xxxxx.prototype = {
dxxxx: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

你必须添加// eslint-disable-line react/forbid-prop-types,然后它工作!

我得到了完全相同的错误,做这个代替:

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

它意味着你的导入/导出错误

  • 检查新添加的import/exports
  • 在我的例子中,我不必要地使用了大括号。当我去掉这些花括号时,问题就自动解决了。
import { OverlayTrigger } from 'react-bootstrap/OverlayTrigger';
// @flow


import React from 'react';
import { styleLocal } from './styles';
import {
View,
Text,
TextInput,
Image,
} from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';


export default React.forwardRef((props, ref) => {
const { onSeachClick, onChangeTextSearch , ...otherProps } = props;


return (
<View style={styleLocal.sectionStyle}>
<TouchableOpacity onPress={onSeachClick}>
<Image
source={require('../../assets/imgs/search.png')}
style={styleLocal.imageStyle} />
</TouchableOpacity>
<TextInput
style=\{\{ flex: 1, fontSize: 18 }}
placeholder="Search Here"
underlineColorAndroid="transparent"
onChangeText={(text) => { onChangeTextSearch(text) }}
/>
</View>
);
});
import IGPSSearch from '../../components/IGPSSearch';
<Search onSeachClick={onSeachClick} onChangeTextSearch= {onChangeTextSearch}> </Search>

我也得到了这个错误。

我用的是:

import ReactDOM from 'react-dom';

费克斯是这样做的:

import {ReactDOM} from 'react-dom';

在我的例子中,我添加了相同的自定义组件作为道具,而不是实际的道具

   import AddAddress from '../../components/Manager/AddAddress';
    

class Add extends React.PureComponent {
render() {
const {
history,
addressFormData,
formErrors,
addressChange,
addAddress,
isDefault,
defaultChange
} = this.props;
    

错误:

    return (
<AddAddress
addressFormData={addressFormData}
formErrors={formErrors}
addressChange={addressChange}
addAddress={AddAddress} // here i have used the Component name as probs in same component itself instead of prob
isDefault={isDefault}
defaultChange={defaultChange}
/>
</SubPage>

解决方案:

return (
<AddAddress
addressFormData={addressFormData}
formErrors={formErrors}
addressChange={addressChange}
addAddress={addAddress} // removed the component name and give prob name
isDefault={isDefault}
defaultChange={defaultChange}
/>
</SubPage>

我正在开发的应用程序将react组件的名称作为小部件配置存储在浏览器存储中。其中一些组件被删除了,应用程序仍在试图呈现它们。通过清除浏览器缓存,我能够解决我的问题。

所以我遇到了这个问题,我用一种奇怪的方式解决了它。我想我应该把它扔了,以防其他人遇到它,变得绝望。

我有一个有条件地呈现react元素,它只在对象状态大于零时才会呈现。在呈现函数中-当三元运算符被证明为真时,我收到了这篇文章所涉及的错误。我在我的渲染函数中使用了<React.Fragment> -这是我通常对子元素进行分组的方式,而不是使用更新的短语法(<> and </>)的更新方式。

然而,当我将<React.Fragment>更改为短语法时- react元素正确呈现,错误停止出现。我看了一下facebook的React-Fragment文档,我没有看到任何理由在那里相信两者之间有一个戏剧性的差异,会导致这个。无论如何,下面是两个简化的代码片段供您查看。第一个演示了产生错误的代码,第二个演示了修复问题的代码。底部是组件本身的渲染函数。

希望有人觉得这有帮助。

代码示例1 -错误 有条件渲染的React元素


renderTimeFields = () => {
return (
<React.Fragment>
<div className="align-left">
<div className="input-row">
<label>Date: </label>
<input type="date" className="date" name="date" min={new Date().toISOString().split('T')[0]} required/>
</div>
</div>
<div className="align-left sendOn-row">
<div className="input-row">
<label>Time: </label>
<input type="time" className="time" name="time" required/>
</div>
</div>
</React.Fragment>
);
}

代码示例2 -无错误 有条件渲染的React元素


renderTimeFields = () => {
return (
<>
<div className="align-left">
<div className="input-row">
<label>Date: </label>
<input type="date" className="date" name="date" min={new Date().toISOString().split('T')[0]} required/>
</div>
</div>
<div className="align-left sendOn-row">
<div className="input-row">
<label>Time: </label>
<input type="time" className="time" name="time" required/>
</div>
</div>
</>
);
}

在组件中呈现函数

render() {
<form>
...
{emailsInActiveScript > 1 ? this.renderTimeFields() : null}
</form>
etc...
}

我的情况不像上面许多人说的那样是一个重要的问题。在我的版本中,我们使用了一个包装器组件来做一些转换逻辑,我错误地传递了子组件,就像这样:

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

当我应该把它作为一个函数传递的时候:

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

对我来说,我有两个名称相同但扩展名不同的文件(.js和.tsx)。因此在我的导入中,我必须指定扩展名。

在我的情况下,VS代码让我失望。

这是我的组件的层次结构:

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

我错误地导入了ProductItemComponent。事实上,这个组件以前在共享文件夹中,但后来它被移动到主文件夹中。但是当我将文件移动到另一个文件夹时,导入没有更新,保持不变:

../shared/components

同时,组件工作正常,VS Code没有突出显示错误。但是当我添加一个新的BadgeProductComponent到ProductItemComponent时,我有一个渲染错误,并认为问题是在新的BadgeProductComponent中,因为当这个组件被删除时,一切都工作了!

更重要的是,如果我通过热键到ProductItemComponent它有。/共享/components地址,然后VS Code将我重定向到带有地址../首页/components的Home文件夹。

一般来说,检查所有组件级别上所有导入的正确性

我也有类似的问题。发生这种情况是因为我在父组件中导入了一个被删除并且实际上不存在的子组件。我审查了每个导入的父组件,在这种情况下,父组件是ListaNegra.js

enter image description here

对我来说,删除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>
);
}

我已经遇到过这个问题了。我的解决方案是:

在文件配置路由:

const routes = [
{ path: '/', title: '', component: Home },
{ path: '*', title: '', component: NotFound }
]

:

const routes = [
{ path: '/', title: '', component: <Home /> },
{ path: '*', title: '', component: <NotFound /> }
]

当我将nothingundefined作为值传递给我创建的子组件时,发生了这个问题。我做了这个<MyComponent src="" />,导致错误。然后将其更改为<MyComponent src=" " />,因为我真的不想传递任何东西…问题解决了。

对于我来说,这发生在我试图将命名导入作为默认导入时,所以我得到了这个错误

import ProductCard from '../../../components/ProductCard' // that what caused the issue
Error: Element 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, or you might have mixed up default and named imports.


Check the render method of `TopVente`.

所以我必须通过名称导入来修复它

import { ProductCard } from '../../../components/ProductCard'
在我的例子中,我导入Avatar为like 进口{ 《阿凡达》 }从'react-native-paper'; 在渲染时,我在TouchableOpacity中包装了Avatar元素,这导致了上述问题。移除TouchableOpacity后,一切正常。 & lt;《阿凡达》。图像 =\{\{来源 uri:“……” }} 大小= {80} /在< / p >

在我的例子中,在使用Jest时,我模拟了一些模块,它导致了错误,因为模拟的模块不包括在其他领域使用的某些组件。

因此,请检查您的测试组件中是否有一些模拟函数。

在我的例子中,我的组件中有文本组件,当我像这样导入不带花括号的Text时,这就是错误的原因

import Text from '..';  <-wrong

为了修复这个错误,我像这样在花括号内导入Text

import {Text} from '..';  <-right

你可能会从某个文件返回object而不是只返回语句

错误的:

import React from 'react'
const About = () => {   return ( <div>About</div>   ) }
export default About

正确的:

import React from 'react'
const About = () => {   return
<div>About</div>}
export default About