One place for hosting & domains

      рендеринга

      Процедура рендеринга массивов в React


      Введение

      В этой статье рассказывается о рендеринге массивов в React и о лучших практиках для рендеринга разных элементов внутри компонентов.

      Одно из преимуществ использования современных языков веб-разработки, включая JavaScript, заключается в возможности быстро автоматизировать генерирование блоков кода HTML.

      Использование циклов в отношении массивов или объектов означает, что для каждого элемента код HTML нужно писать только один раз. Более того, любые будущие изменения также потребуется вносить только один раз.

      Рендеринг множества элементов

      Чтобы выполнить рендеринг множества элементов JSX в React, вы можете применить к массиву цикл с методом .map() и возвращением одного элемента.

      В примере ниже мы применяем цикл к массиву reptiles и получаем элемент li для каждого элемента в массиве. Вы можете использовать этот метод, если хотите вывести один элемент для каждого элемента массива:

      function ReptileListItems() {
        const reptiles = ["alligator", "snake", "lizard"];
      
        return reptiles.map((reptile) => <li>{reptile}</li>);
      }
      

      Итоговый результат будет выглядеть следующим образом:

      Output

      - alligator - snake - lizard

      В следующем примере мы увидим, почему лучше добавлять уникальный ключ к списку элементов, рендеринг которых выполняет массив.

      Рендеринг набора элементов внутри компонента

      В этом примере, как и в предыдущем, мы применяем к массиву цикл и создаем серию компонентов элемента списка.

      Для начала обновите код, чтобы использовать компонент <ol> для хранения элементов <li>. Компонент <ol> создаст упорядоченный список элементов:

      function ReptileList() {
        const reptiles = ["alligator", "snake", "lizard"];
      
        return (
          <ol>
            {reptiles.map((reptile) => (
              <li>{reptile}</li>
            ))}
          </ol>
        );
      }
      

      Однако, если вы посмотрите на консоль, вы увидите предупреждение о том, что каждый дочерний элемент массива или итератора должен иметь уникальный ключ.

      Предупреждение в консоли

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

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

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

      function ReptileList() {
        const reptiles = ['alligator', 'snake', 'lizard'];
      
        return (
          <ol>
            {reptiles.map(reptile => (
              <li key={reptile}>{reptile}</li>
            ))}
          </ol>
        );
      }
      
      

      После добавления ключа предупреждение больше не будет отображаться внутри консоли.

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

      Рендеринг прилегающих элементов

      Для рендеринга одного или нескольких элементов компонента в JSX необходимо заключить их в оболочку.

      В этом примере мы сначала возвращаем список элементов без применения цикла к массиву:

      function ReptileListItems() {
        return (
          <li>alligator</li>
          <li>snake</li>
          <li>lizard</li>
        );
      }
      

      При этом в консоли выводится постоянная ошибка:

      Постоянная ошибка React для прилегающих элементов JSX

      Чтобы исправить эту ошибку, необходимо заключить блок элементов li в оболочку. Для списка их можно заключить в элемент ol или ul:

      function ReptileListItems() {
        return (
        <ol>
          <li>alligator</li>
          <li>snake</li>
          <li>lizard</li>
        </ol>
        );
      }
      

      Прилегающие элементы <li> теперь заключены в тег <ol>, и ошибка больше отображаться не будет.

      В следующем разделе список выводится в оболочке с использованием компонента fragment.

      Рендеринг прилегающих элементов с помощью React.fragment

      До React v16.2 была возможность заключать блоки компонентов в элементе <div>. При этом получается приложение с большим количеством тегов div, и такие приложения часто называли «суп div».

      Для устранения этой проблемы для React был выпущен новый компонент fragment:

      Если требуется выполнить рендеринг списка внутри тега, но вы не хотите использовать теги div, вы можете использовать React.Fragment:

      function ReptileListItems() {
        return (
        <React.Fragment>
           <li>alligator</li>
           <li>snake</li>
           <li>lizard</li>
        </React.Fragment>
        );
      }
      

      Код после рендеринга будет содержать только элементы li, и компонент React.Fragment не будет отображаться в коде.

      Элементы JSX внутри оболочки React.Fragment

      Также в случае с React.fragment следует отметить, что ключ добавлять не требуется.

      Можно отметить, что React.fragment писать сложнее, чем добавлять теги <div>. К счастью, команда React разработала более короткий синтаксис для представления этого компонента. Можно использовать <> </> вместо <React.Fragment></React.Fragment>:

      function ReptileListItems() {
        return (
       <>
          <li>alligator</li>
          <li>snake</li>
          <li>lizard</li>
       </>
        );
      }
      

      Заключение

      В этой статье мы рассмотрели разные примеры рендеринга массивов в приложении React.

      При рендеринге элемента внутри другого компонента следует использовать уникальный ключ и заключать элементы в элемент оболочки.

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

      Чтобы узнать больше о лучших практиках React, подпишитесь на серию Программирование на React.js на DigitalOcean.



      Source link

      Включение рендеринга на стороне сервера для приложения React


      Введение

      Рендеринг на стороне сервера (SSR) — это популярная методика рендеринга одностраничного клиентского приложения (SPA) на сервере и последующей отправки на клиент полностью отрисованной страницы. Это позволяет использовать динамические компоненты в качестве статической разметки HTML.

      Такой подход может быть полезным для поисковой оптимизации (SEO), когда при индексации код JavaScript не обрабатывается надлежащим образом. Это также может быть полезно в ситуациях, когда загрузка большого блока JavaScript затруднена из-за медленной скорости сети.

      В этом учебном модуле мы инициализируем приложение React с помощью Create React App, а затем изменим проект, чтобы он активировал рендеринг на стороне сервера.

      После прохождения учебного модуля вы получите работающий проект с клиентским приложением React и серверным приложением Express.

      Примечание. Также Next.js позволяет использовать современный подход к созданию статических приложений React и приложений, рендеринг которых выполняется на сервере.

      Предварительные требования

      Для данного обучающего руководства вам потребуется следующее:

      Этот учебный модуль был проверен с версиями Node v14.4.0 и npm v6.14.5.

      Шаг 1 — Создание приложения React и изменение компонента приложения

      Вначале мы используем npx для запуска нового приложения React с помощью последней версии Create React App.

      Назовем наше приложение my-ssr-app:

      • npx create-react-app@3.4.1 my-ssr-app

      Перейдем в новый каталог с помощью команды cd:

      cd my-ssr-app
      

      В заключение мы запустим наше новое приложение на стороне клиента для проверки установки:

      Вы должны увидеть пример приложения React в окне браузера.

      Теперь создадим компонент <Home>:

      Затем добавим следующий код в файл Home.js:

      src/Home.js

      import React from 'react';
      
      export default props => {
        return <h1>Hello {props.name}!</h1>;
      };
      

      При этом будет создан заголовок <h1> с сообщением "Hello“, адресованным имени.

      Далее мы выполним рендеринг <Home> в компоненте <App>. Откройте файл App.js:

      Затем заменим существующие строки кода новыми строками кода:

      src/App.js

      import React from 'react';
      import Home from './Home';
      
      export default () => {
        return <Home name="Sammy" />;
      };
      

      Они передают name в компонент <Home> так, что ожидаемое сообщение будет выглядеть так: "Hello Sammy!".

      В файле index.js нашего приложения мы будем использовать метод ReactDOM hydrate вместо render, чтобы указать блоку рендеринга DOM, чтобы мы восстанавливаем приложение после рендеринга на стороне сервера.

      Откроем файл index.js:

      Замените содержимое файла index.js следующим кодом:

      index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import App from './App';
      
      ReactDOM.hydrate(<App />, document.getElementById('root'));
      

      Мы завершили настройку на стороне клиента и теперь можем перейти к настройке на стороне сервера.

      Шаг 2 — Создание сервера Express и рендеринг компонента приложения

      Теперь наше приложение готово, и мы настроим сервер, который будет отправлять готовую версию после рендеринга. Для сервера мы будем использовать Express. Добавим его в проект, введя следующую команду в окне терминала:

      • npm install express@4.17.1

      Также можно использовать yarn:

      Создайте каталог server рядом с каталогом src нашего приложения:

      Затем создайте новый файл index.js, содержащий код сервера Express:

      Добавим необходимые элементы импорта и определим некоторые константы:

      server/index.js

      import path from 'path';
      import fs from 'fs';
      
      import React from 'react';
      import express from 'express';
      import ReactDOMServer from 'react-dom/server';
      
      import App from '../src/App';
      
      const PORT = process.env.PORT || 3006;
      const app = express();
      

      Затем добавим код сервера с обработкой ошибок:

      server/index.js

      // ...
      
      app.get('/', (req, res) => {
        const app = ReactDOMServer.renderToString(<App />);
      
        const indexFile = path.resolve('./build/index.html');
        fs.readFile(indexFile, 'utf8', (err, data) => {
          if (err) {
            console.error('Something went wrong:', err);
            return res.status(500).send('Oops, better luck next time!');
          }
      
          return res.send(
            data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
          );
        });
      });
      
      app.use(express.static('./build'));
      
      app.listen(PORT, () => {
        console.log(`Server is listening on port ${PORT}`);
      });
      

      Как видите, мы можем импортировать наш компонент <App> из клиентского приложения непосредственно с сервера.

      Здесь происходит три важные вещи:

      • Мы предписываем Express вывести содержимое каталога build в виде статичных файлов.
      • Мы будем использовать метод ReactDOMServer, renderToString, для рендеринга нашего приложения в статичную строку HTML.
      • Затем мы считываем статичный файл index.html из готового клиентского приложения, вставляем статичное содержимое нашего приложения в <div> с id "root", а затем отправляем результат в качестве ответа на запрос.

      Шаг 3 — Настройка webpack, Babel и скриптов npm

      Чтобы наш серверный код работал, нам нужно объединить его в комплект и провести транспиляцию, используя webpack и Babel. Для этого добавим в проект зависимости dev, введя следующую команду в окне терминала:

      • npm install webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --save-dev

      Также можно использовать yarn:

      • yarn add webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --dev

      Примечание. В более ранней версии этого учебного модуля мы устанавливали babel-core, babel-preset-env и babel-preset-react-app. Эти пакеты с тех пор были архивированы, и вместо них используются версии с одним репозиторием.

      Далее мы создадим файл конфигурации Babel:

      После этого добавьте готовые настройки env и react-app:

      .babelrc.json

      {
        "presets": [
          "@babel/preset-env",
          "@babel/preset-react"
        ]
      }
      

      Примечание. В более ранней версии этого учебного модуля мы использовали файл .babelrc (без расширения .json). Это был файл конфигурации Babel 6, однако для Babel 7 он больше не используется.

      Теперь мы создадим конфигурацию webpack для сервера, который использует Babel Loader для транспиляции кода. Начните с создания файла:

      Затем добавьте следующие конфигурации в файл webpack.server.js:

      webpack.server.js

      const path = require('path');
      const nodeExternals = require('webpack-node-externals');
      
      module.exports = {
        entry: './server/index.js',
      
        target: 'node',
      
        externals: [nodeExternals()],
      
        output: {
          path: path.resolve('server-build'),
          filename: 'index.js'
        },
      
        module: {
          rules: [
            {
              test: /.js$/,
              use: 'babel-loader'
            }
          ]
        }
      };
      

      С этой конфигурацией наш транспилированный серверный комплект будет выводиться в папку server-build в файле с именем called index.js.

      Обратите внимание на использование target: 'node' и externals: [nodeExternals()] из webpack-node-externals. При этом опускаются файлы из node_modules в комплекте, сервер сможет получить доступ к этим файлам напрямую.

      Это завершает установку зависимости и конфигурации webpack и Babel.

      Теперь мы снова вернемся к файлу package.json и добавим вспомогательные скрипты npm:

      Мы добавим скрипты dev:build-server, dev:start и dev в файл package.json, чтобы легко выполнять сборку и подачу нашего приложения SSR:

      package.json

      "scripts": {
        "dev:build-server": "NODE_ENV=development webpack --config webpack.server.js --mode=development -w",
        "dev:start": "nodemon ./server-build/index.js",
        "dev": "npm-run-all --parallel build dev:*",
        ...
      },
      

      Мы используем nodemon для перезапуска сервера при внесении изменений. Также мы используем npm-run-all для параллельного выполнения нескольких команд.

      Давайте установим эти пакеты, введя следующие команды в окне терминала:

      • npm install nodemon@2.0.4 npm-run-all@4.1.5 --save-dev

      Также можно использовать yarn:

      • yarn add nodemon@2.0.4 npm-run-all@4.1.5 --dev

      Так вы можете запустить следующий код для сборки приложения на стороне клиента, объединения в пакет и транспиляции кода сервера и запуска сервера на порту :3006:

      Также можно использовать yarn:

      Наша конфигурация сервера webpack будет следить за изменениями, и в случае изменений наш сервер перезапустится. Однако для клиентского приложения нам нужно выполнять сборку каждый раз при внесении изменений. Для этого есть открытая проблема.

      Откройте в браузере адрес http://localhost:3006/ и вы увидите приложение после рендеринга на стороне сервера.

      Ранее исходный код показал следующее:

      Output

      <div id="root"></div>

      С внесенными изменениями исходный код показывает:

      Output

      <div id="root"><h1 data-reactroot="">Hello <!-- -->Sammy<!-- -->!</h1></div>

      При рендеринге на стороне сервера компонент <App> был успешно конвертирован в формат HTML.

      Заключение

      В этом учебном модуле мы инициализировали приложение React и активировали рендеринг на стороне сервера.

      Так мы просто оценили доступные возможности. Все становится сложнее, если в приложение после рендеринга на стороне сервера нужно добавить маршрутизацию, доставку данных или Redux.

      Преимущество использования SSR заключается в наличии приложения, содержимое которого может просмотреть даже сборщик, не выполняющий код JavaScript. Это поможет для поисковой оптимизации (SEO) и отправки метаданных на каналы социальных сетей.

      SSR также часто помогает решить проблемы с производительностью, потому что полностью загруженное приложение отправляется с сервера при первом запросе. С необычными приложениями ситуация может меняться, потому что SSR требует довольно сложной настройки и создает более существенную нагрузку на сервер. Использование рендеринга на стороне сервера для приложения React зависит от конкретных потребностей и от того, какие компромиссы имеют смысл для вашего сценария использования.

      Если вы хотите узнать больше о React, почитайте нашу серию «Программирование на React.js» или посмотрите страницу тем React, где вы найдете упражнения и программные проекты.



      Source link