尝试得到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;

当前回答

对我来说,我导入阿凡达就像 进口{ 《阿凡达》 }从'react-native-paper'; 在渲染时,我在TouchableOpacity中包装了Avatar元素,这导致了上述问题。移除TouchableOpacity后,一切正常。 <阿凡达。图像 ={{来源 uri:“……” }} 大小= {80} />

其他回答

组件数组

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

const checkoutSteps = [Address, Shipment, Payment]

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

  const ToRender = checkoutSteps[step]

  return (
    <ToRender />
  )
}

这不是必要的坏代码,但如果你用一个错误的索引(例如-1,或者在这种情况下是3)调用它,ToRender组件将是未定义的,抛出React。createElement:类型无效…错误:

<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代表…) 错误也是显式的 不会让你的同事头疼:)

当我在我的渲染/返回语句中有一个糟糕的引用时,这个问题出现在我身上。(指向不存在的类)。 还要检查return语句代码中的错误引用。

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

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

示例:

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

EDIT

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

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;