Нарушение инварианта: недопустимый тип элемента: ожидал строку или класс, но получил: не определено. Проверьте метод рендеринга MyApp

Я пытаюсь загрузить статический 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 и sin.request.url в качестве реквизита

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 без передачи каких-либо реквизитов:

sink.renderIntoElementById('app', renderToString(React.createElement(MyApp)));

5) комментируя следующее, просто чтобы увидеть, вызвано ли это каким-либо из моих других импортированных компонентов

<Route path = "/" component = {HomePage}/>

🤔 А знаете ли вы, что...
JavaScript - это скриптовый язык программирования, разработанный Netscape Communications Corporation.


1
66
1

Ответ:

Решено

Я наконец понял проблему. Оказывается, простое использование react-router не позволяет мне использовать компоненты с поддержкой DOM, такие как и , поэтому вместо этого мне нужно было использовать react-router-dom. react-router-dom также реэкспортирует весь экспорт 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