Нужна помощь в настройке реакции-hot-loader

Я использую последний ASP.NET 2.0 шаблон реагирования SPA, который создается с помощью команды dotnet new реагировать. Он отлично работает из коробки, с горячей заменой модуля (изменения кода обновляются в браузере автоматически).

Затем я хотел добавить контейнер приложений верхнего уровня, который называется App для хранения состояния приложения, как описано в этом сообщении в блоге: реагируйте без избыточной статьи. Должно быть просто, верно? Обратите внимание, что в статье используется javascript, но я использую Typescript, поскольку именно так был разработан шаблон. Но после добавления простого компонента контейнера верхнего уровня и обновления конфигурации горячего загрузчика он не работает. Я получаю сообщение об ошибке, что компонент не знает, как перезагрузить себя. Это код, который работает (из шаблона):

import './styles/site.scss';
import 'bootstrap';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { BrowserRouter } from 'react-router-dom';
import * as RoutesModule from './routes';
let routes = RoutesModule.routes;

function renderApp() {
    // This code starts up the React app when it runs in a browser. It sets up the routing
    // configuration and injects the app into a DOM element.
    const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
    ReactDOM.render(
        <AppContainer>
            <BrowserRouter children={ routes } basename={ baseUrl } />
        </AppContainer>,
        document.getElementById('react-app')
    );
}

renderApp();

// Allow Hot Module Replacement
if (module.hot) {
    module.hot.accept('./routes', () => {
        routes = require<typeof RoutesModule>('./routes').routes;
        renderApp();
    });
}

И это код после моих изменений, который НЕ работает:

import './styles/site.scss';
import 'bootstrap';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { BrowserRouter } from 'react-router-dom';
import * as RoutesModule from './routes';
import  App  from './components/App';
import * as AppModule from './components/App'

let routes = RoutesModule.routes;

const render = (Component: any) => {
    // This code starts up the React app when it runs in a browser. It sets up the routing
    // configuration and injects the app into a DOM element.
    //const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
    ReactDOM.render(
        <AppContainer>
            <Component />
        </AppContainer>,
        document.getElementById('react-app')
    );
}

render(App);

// Allow Hot Module Replacement
if (module.hot) {
    module.hot.accept('./components/App', () => {
        const nextRoot = (require('./components/App') as typeof AppModule).default;
        render(nextRoot);
    });
}

Для справки вот файл./routes (я не менял этот файл):

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';

export const routes = <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={ FetchData } />
</Layout>;

И вот мой новый компонент контейнера приложения:

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { BrowserRouter } from 'react-router-dom';
import * as RoutesModule from '../routes';
import { ReactElement } from "react";
let routes = RoutesModule.routes;

interface AppState {
    stateDescription: string;
}

export default class App extends React.Component<{}, {}> {
    constructor(props: any) {
        super(props);
        this.state = { stateDescription: 'My Cool App State' };
    }

    public render() {
        const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!;
        return (
            <BrowserRouter children = { routes } basename = { baseUrl } />
        );
    }
}

Любые идеи или предложения будут высоко оценены!

1 ответ

Я смог решить эту проблему, вернув мой файл boot.tsx к исходной версии шаблона и поместив вместо этого мой компонент приложения в файл rout.tsx. Вы можете видеть, что я только что завернул все в новый элемент App. Вот новый файл route.tsx:

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import { App } from './components/App';

export const routes = <App>
  <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={ FetchData } />
  </Layout>
</App>;

А вот мой модифицированный компонент приложения, который работает с этой версией:

export class App extends React.Component<AppProps, {}> {
    constructor(props: AppProps) {
        super(props);
        this.state = { stateDescription: 'My Cool App State' };
    }

    public render() {
        return (
            <div className='appContainer'>
                { this.props.children }
            </div>
        );
    }
}
Другие вопросы по тегам