Разделение кода Webpack 2 с рендерингом на стороне сервера и React-Router-v4

Использование webpack2.2.0-rc1 и react routerv4, а также использование этого gist, чтобы разделение кода работало , в котором говорится следующее

function asyncComponent(getComponent) {
  return class AsyncComponent extends React.Component {
    static Component = null;
    state = { Component: AsyncComponent.Component };

    componentWillMount() {
      if (!this.state.Component) {
        getComponent().then(Component => {
          AsyncComponent.Component = Component
          this.setState({ Component })
        })
      }
    }
    render() {
      const { Component } = this.state
      if (Component) {
        return <Component {...this.props} />
      }
      return null
    }
  }
}

const Foo = asyncComponent(() =>
  System.import('./Foo').then(module => module.default)
)

Это действительно работает, но я использую рендеринг на стороне сервера. Итак, на сервере мне нужен компонент A, затем на клиенте я System.import компонент A. Наконец, когда я получаю доступ к ленивому загруженному маршруту, я получаю это предупреждение о повторном использовании разметки, потому что клиент отображал изначально загруженный нуль из https://gist.github.com/acdlite/a68433004f9d6b4cbc83b5cc3990c194#file-app-js-L21 при загрузке компонента A. Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server: (client) CO 0.0.0 </h1></div><!-- react-empty: 6 - (server) CO 0.0.0 </h1> </div><div data-radium="tru

Как я могу заставить это работать без ошибок?


person CESCO    schedule 19.01.2017    source источник


Ответы (1)


Я только что изменил эту строку в AsyncComponent, чтобы сделать ее вернуть тормозной тег
, пока компонент с разделенным кодом еще не загружен. Затем вместо того, чтобы требовать от фактического компонента рендеринга на стороне сервера, я просто добавляю еще один тормозной тег, чтобы разметка действительно совпадала.

Это далеко от идеала

export function Shell(Component) {
    return React.createClass({
        render: function () {
            return (
                <div>
                    <Bar/>
                    <Component {...this.props}/>
                </div>
            );
        }
    });
};

export const Waiting = React.createClass({
    render: function () {
        return (
            <div>
                <Bar/>
                <br/>
            </div>
        );
    }
});


// Client routes
const AsyncDash = Utils.asyncRoute(() => System.import("../components/dashboard/dashboard.tsx"));
const AsyncLogin = Utils.asyncRoute(() => System.import("../components/login/login"));

const routes = () => {
    return (<div>
            <Match exactly pattern="/" component={Shell(AsyncLogin)}/>
            <Match exactly pattern="/dashboard" component={Shell(AsyncDash)}/>
        </div>
    );
};


// Server routes
const routes = () => {
    return (<div>
            <Match exactly pattern="/" component={Waiting}/>
            <Match exactly pattern="/dashboard" component={Waiting}/>
        </div>
    );
};
person CESCO    schedule 20.01.2017
comment
Вы нашли решение для этого? - person Nat Homer; 30.06.2017
comment
Множество решений. React-async-component, старый хак. Просто не надо. React-загружаемый, новый хак. React-universal-component даже лучше нового хака. - person CESCO; 30.06.2017