Как отобразить целевую страницу на сервере, а остальное — на стороне клиента?

#javascript #node.js #reactjs #webpack #babeljs

#javascript #node.js #reactjs #webpack #babeljs

Вопрос:

Я довольно новичок в концепциях рендеринга на стороне сервера. Я использую react и хотел создать только одну страницу, то есть домашнюю страницу, отображаемую на сервере. После этого любое действие, которое предпринимает пользователь, должно быть отображено на стороне клиента.

Я пытаюсь создать одностраничное приложение, которое извлекает данные из базы данных, но при первой загрузке я хочу, чтобы сервер отправил отображенную страницу в браузер.

Ответ №1:

Одним из вариантов было бы создать, например, приложение Express / Node или простой статический веб-сайт, куда вы затем включаете скрипт, сгенерированный с помощью React (с <script> тегами). Я делал это раньше.

РЕДАКТИРОВАТЬ // Вот мой проект с приложениями как на стороне клиента, так и на стороне сервера. Ссылка

Например:

Компонент React:

 import React from 'react';
import ReactDOM from 'react-dom';

import { AddEdge, AddNode } from '../components';

class Component extends React.Component {
  render() {
    const { nodes, addNode, addEdge } = this.props;

    return (
      <div>
        <AddNode
          addNodeCallback={addNode}
        />
        <AddEdge
          nodes={nodes}
          addEdgeCallback={addEdge}
        />
      </div>
    );
  }
}

export const render = (nodes, addNode, addEdge) => {
  ReactDOM.render(
    <Component
      nodes={nodes}
      addNode={addNode}
      addEdge={addEdge}
    />,
    document.getElementById('reactContainer'),
  );
};
  

Фрагмент кода на стороне сервера:

  app.get('/:categoryName/:pageName', async (req, res) => {
    const navData = await getNavData();
    const { categoryName, pageName } = req.params;

    const category = navData.categories
      .find(category => `${category.name}`.toLowerCase() === parseParam(categoryName));
    const page = navData.pages
      .find(page => `${page.name}`.toLowerCase() === parseParam(pageName));

    if (!category || !page) {
      res.render('notFound', { ...navData });
      return;
    }

    fs.readFile(
      path.resolve(__dirname, '..', 'content', 'md', `${category.id}_${page.templateFile}`),
      (err, data) => {
        if (err) {
          res.render('error', { ...navData, message: err.message });
          return;
        }

        res.render('page', { ...navData, category, page, markdown: data.toString().replace(/n/g, '\n').replace(/r/g, '') });
      }
    )
  });
  

HTML-макет на стороне сервера

 <div class="container-fluid">
  <div class="row">
    <div class="col-sm">
      <div id="md"></div>
      <div id="reactContainer"></div>
    </div>
    <div class="col-sm">
      <div id="graphContainer" class="graph-container"></div>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.1/showdown.min.js"></script>
<script>
  var converter = new showdown.Converter();
  document.getElementById('md').innerHTML = converter.makeHtml('{{{markdown}}}');
</script>

<script src="{{urlBase}}/graphs/vendors.js"></script>
<script src="{{urlBase}}/graphs/{{category.id}}_{{page.jsFile}}"></script>
  

Комментарии:

1. Я добавил материал о моем примере проекта

2. Для ясности, клиентской стороной может быть одностраничное приложение React (или Angular, или Vue), а сервером может быть что угодно , не ограниченное node (сервером может быть Ruby, PHP, Java, C # и т.д.)