不变违规:元素类型无效:应为字符串或 class 但得到:未定义。检查 `MyApp` 的渲染方法
Invariant Violation: Element type is invalid: expected a string or a class but got: undefined. Check the render method of `MyApp`
我正在尝试从也使用 redux 和路由器的流星服务器端加载静态 HTML。但是,每次我尝试使用 renderToString() 渲染我的组件时,我都会收到标题中指示的错误。我做错了什么?
我已经尝试使用 React.renderComponentToString 作为可能的替代方法,但我得到的错误是 React.renderComponentToString 不是一个函数。我还可以通过什么方式进行辩论?
import React from 'react';
import {onPageLoad} from 'meteor/server-render';
import {StaticRouter} from 'react-router';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import {Helmet} from 'react-helmet';
import rootReducer, {initialState} from '../redux/reducers';
import HomePage from '../ui/homepage/HomePage';
export default renderServerPage = onPageLoad(sink => {
const context = {};
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
const MyApp = props => {
return (
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
// The following line is causing the error
sink.renderIntoElementById('app', renderToString(<MyApp />));
const helmet = Helmet.renderStatic();
sink.appendToHead(helmet.title.toString(
"Afterschools, Enrichment Programs, Growth, & Experiences - Fun2Bright"
));
sink.appendToBody(
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\u003c')}
</script>
);
});
我的其他尝试包括:
1) 在同一个文件中创建一个超出范围的组件,并将 store 和 sink.request.url 作为 props
传递
function MyApp (props) {
const context = {};
return (
<Provider store={props.store}>
<StaticRouter location={props.location} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
2) 基本上创建相同的组件,但在另一个文件中并导入组件。
3) 直接将元素放入renderToString:
sink.renderIntoElementById('app', renderToString(
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
));
4) 使用 React.createElement 而不传递任何 props:
sink.renderIntoElementById('app', renderToString(React.createElement(MyApp)));
5) 注释掉以下内容,看看它是否是由我的任何其他导入组件引起的
<Route path="/" component={HomePage}/>
我终于想通了。事实证明,仅使用 react-router
不允许我使用 DOM-aware 组件,例如 and ,因此我需要改用 react-router-dom
。 react-router-dom 也 re-exports 所有 react-router 的出口,所以我只需要使用 react-router-dom
。我将所有内容更改为从 'react-router-dom':
导入
import {Route, StaticRouter} from 'react-router-dom';
...
// inside onPageLoad
const App = props => {
return (
<Provider store={store}>
<StaticRouter location={props.location} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
sink.renderIntoElementById('app', renderToString(<App store={store} location={sink.request.url}/>));
我从这里找到的:https://github.com/ReactTraining/react-router/issues/4648
我正在尝试从也使用 redux 和路由器的流星服务器端加载静态 HTML。但是,每次我尝试使用 renderToString() 渲染我的组件时,我都会收到标题中指示的错误。我做错了什么?
我已经尝试使用 React.renderComponentToString 作为可能的替代方法,但我得到的错误是 React.renderComponentToString 不是一个函数。我还可以通过什么方式进行辩论?
import React from 'react';
import {onPageLoad} from 'meteor/server-render';
import {StaticRouter} from 'react-router';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import {Helmet} from 'react-helmet';
import rootReducer, {initialState} from '../redux/reducers';
import HomePage from '../ui/homepage/HomePage';
export default renderServerPage = onPageLoad(sink => {
const context = {};
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
const MyApp = props => {
return (
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
// The following line is causing the error
sink.renderIntoElementById('app', renderToString(<MyApp />));
const helmet = Helmet.renderStatic();
sink.appendToHead(helmet.title.toString(
"Afterschools, Enrichment Programs, Growth, & Experiences - Fun2Bright"
));
sink.appendToBody(
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\u003c')}
</script>
);
});
我的其他尝试包括: 1) 在同一个文件中创建一个超出范围的组件,并将 store 和 sink.request.url 作为 props
传递function MyApp (props) {
const context = {};
return (
<Provider store={props.store}>
<StaticRouter location={props.location} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
2) 基本上创建相同的组件,但在另一个文件中并导入组件。
3) 直接将元素放入renderToString:
sink.renderIntoElementById('app', renderToString(
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
));
4) 使用 React.createElement 而不传递任何 props:
sink.renderIntoElementById('app', renderToString(React.createElement(MyApp)));
5) 注释掉以下内容,看看它是否是由我的任何其他导入组件引起的
<Route path="/" component={HomePage}/>
我终于想通了。事实证明,仅使用 react-router
不允许我使用 DOM-aware 组件,例如 and ,因此我需要改用 react-router-dom
。 react-router-dom 也 re-exports 所有 react-router 的出口,所以我只需要使用 react-router-dom
。我将所有内容更改为从 'react-router-dom':
import {Route, StaticRouter} from 'react-router-dom';
...
// inside onPageLoad
const App = props => {
return (
<Provider store={store}>
<StaticRouter location={props.location} context={context}>
<Route path="/" component={HomePage}/>
</StaticRouter>
</Provider>
);
}
sink.renderIntoElementById('app', renderToString(<App store={store} location={sink.request.url}/>));
我从这里找到的:https://github.com/ReactTraining/react-router/issues/4648