Создание базового пользовательского интерфейса с помощью ReactJS

0 Акции
0
0
0
0

Введение

Мы создадим простое чат-приложение на ReactJS на основе уже реализованного нами сервера. Начнём с создания статических компонентов, которые затем подключаются к состоянию. На последнем этапе мы подписываемся на сервер событий.

Предпосылки
  • Базовые знания JavaScript и ReactJS (я стараюсь излагать всё просто)
  • npm v6
  • npx v6
  • узел v12

Шаг 1: Запуск проекта

В папке проекта выполните команду npx create-react-app --use-npm simple-chat-app и дождитесь завершения установки. Это добавит все необходимые зависимости и упростит процесс разработки и сборки.

Добавьте следующие файлы в папку src:

  • App.js (должен уже существовать)
  • ChatLineHolder.js
  • ChatLine.js
  • ChatInput.js

Выполните команду npm run start из папки проекта в консоли. Это запустит сервер разработки и откроет приложение в браузере по умолчанию.

В папке src уже должен быть файл App.js. Пока что вы можете удалить всё, что он возвращает, и оставить только один. <div> Верните его.

const App = () => {
return <div className='chat-app'></div>
}

Мы начинаем с создания наших компонентов снизу вверх.

Шаг 2: Компонент

В ChatLine.js мы создаем новый компонент, имеющий два свойства:

  • имя: нить
  • сообщение: нить

Это данные, которые мы позже получим с сервера как данные о событиях.

Компонент первый

  • Он просто возвращается и отображает имя и сообщение:

    import React from 'react'
    const ChatLine = ({ name, message }) => {
    return (
    <li>
    {name}: {message}
    </li>
    )
    }
    export default

    Примечание: ReactJS автоматически предотвращает внедрение HTML-кода, так что вам не о чем беспокоиться.

    Шаг 3: Компонент

    В ChatHolder.js мы создаем новый компонент, который принимает только одну базу:

    Строки: Массив<{ имя: строка, сообщение: строка }>

    Если линии Если пусто, мы отображаем простое уведомление.

    if (lines.length === 0) {
    return <div>Chat history is empty</div>
    }

    Lines — это массив объектов. Каждый объект имеет имя и сообщение о свойстве. Мы сопоставляем все элементы массива, чтобы получить результат, передавая имя и строку компоненту. Создайте несколько узлов ChatLine.

    const chatLines = lines.map(
    (line, index) => (
    <ChatLine key={index} name={line.name} message={line.message} />
    )
    )

    Тогда результат в

      Выполняем рендеринг и получаем готовый компонент:

      import React from 'react'
      import ChatLine from './ChatLine'
      const ChatLineHolder = ({ lines }) => {
      if (lines.length === 0) {
      return <div>Chat history is empty</div>
      }
      const chatLines = lines.map(
      (line, index) => (
      <ChatLine key={index} message={line.message} name={line.name} />
      )
      )
      return (
      <ul>
      {chatLines}
      </ul>
      )
      }
      export default ChatLineHolder

      Примечание: Обычно в качестве ключа используется уникальный идентификатор. В данном случае можно смело использовать индекс, поскольку связь между индексом и объектом не меняется. В реальном приложении это может привести к серьёзным проблемам.

      Шаг 4: Компонент

      Как вы могли заметить, возможности импорта сообщений по-прежнему нет. Обрабатывает ввод текста и использует функцию обратного вызова при отправке для создания нового сообщения чата при нажатии кнопки. Требуется свойство:

      • onSend: (сообщение: строка) => void

      Компонент пользовательского ввода сохраняет свое состояние и управляет обновлениями.

      const [value, setValue] = useState('')
      const onChange = (event) => {
      setValue(event.target.value)
      }

      При нажатии кнопки «Отправить» вызывается функция onSend с текущим состоянием. Поскольку мы не хотим, чтобы пользователю приходилось вручную очищать поле ввода, мы сбрасываем состояние после вызова onSend.

      const onClickSend = () => {
      onSend(value)
      setValue('')
      }
      

      Вот последний компонент:

      import React, { useState } from 'react'
      const ChatInput = ({ onSend }) => {
      const [value, setValue] = useState('')
      const onChange = (event) => {
      setValue(event.target.value)
      }
      const onClickSend = () => {
      setValue('')
      onSend(value)
      }
      return (
      <div>
      <input type='text' value={value} onChange={onChange} />
      <button onClick={onClickSend}>send</button>
      </div>
      )
      }
      export default ChatInput

      Шаг 5: Компонент

      Режим

      Поскольку наши компоненты не хранят никаких данных, В качестве основного компонента мы используем управление состояниями. У нас есть 3 типа состояний:

      • Имя: Имя пользователя, который общается в чате.
      • chatLines: Массив, представляющий историю чата.
      • eventLister: используется для управления событиями с сервера. (Примечание: я решил поместить прослушиватель в часть.

      (Для простоты в реальном приложении вы можете использовать другой подход.)

      Для инициализации нашего состояния мы используем хуки состояния:

       const [chatLines, setChatLines] = useState([])
      const [eventListener, setEventListener] = useState(null)
      const [name] = useState(generateRandomName())

      Тест рендеринга компонентов

      Сейчас мы просто отображаем наше имя и компонент. Мы представляем chatLines с фиксированными элементами. Поскольку chatLines — пустой массив, наше уведомление должно быть отправлено. Мы вызываем пустую функцию Flash, чтобы Мы отправим. Исполнение последует на следующем этапе.

      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={() => {}} />
      </div>
      )

      Если вы хотите проверить, работает ли ваша реализация с некоторыми данными, просто добавьте несколько элементов в chatLines.

      const [chatLines, setChatLines] = useState([{ name: 'Thomas', 'message': 'Hi' }])
      

      Добавить взаимодействие

      Мы уже можем вводить текст в поле ввода чата, но нажатие кнопки «Отправить» ничего не даёт. Это связано с тем, что у нас есть функция, которая называется Мы отправили его, который абсолютно ничего не делает. Поэтому нам нужна реализация.

      Поскольку мы ещё не подключены к серверу, мы реализуем onSend таким образом, чтобы он напрямую обновлял состояние. Для этого добавим вспомогательную функцию addChatLine: (chatLine) => void. Мы будем использовать её позже для обработки сообщений, отправляемых сервером.

      const addChatLine = (chatLine) => {
      setChatLines(chatLines => {
      return [...chatLines, chatLine]
      })
      // If you don't have a lot of experience with ReactJS, just think of this as:
      // setChatLines([...chatLines, chatLine])
      }

      onSend создает объект строки чата и вызывает addChatLine

      const onSend = (message) => {
      const chatLine = { name, message }
      addChatLine(chatLine)
      }

      Не забудьте отправить Отправлять.

      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={onSend} />
      </div>
      )

      Теперь вы сможете ввести текст в поле ввода, нажать «Отправить» и мгновенно увидеть свое сообщение.

      Шаг 6: Подключитесь к серверу

      Общаться с самим собой очень скучно. Поэтому нам нужно подключить наше приложение к серверу. Это происходит в два этапа:

      • Отправить сообщение на сервер
      • Подписаться на события, отправленные сервером
      Отправить сообщение на сервер

      Нам нужно изменить написанную нами функцию onSend. Мы можем заменить всё тело простым вызовом fetch, который отправляет наше имя и сообщение. Важно не вызывать addChatLine, так как мы сделаем это позже, когда получим событие, отправленное сервером.

      const onSend = async (message) => {
      fetch('http://localhost:4000/say',
      {
      headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      },
      method: 'post',
      mode: 'no-cors',
      body: `name=${name}&message=${message}`
      })
      }

      Если вы нажмёте кнопку «Отправить» сейчас, запрос будет отправлен на сервер, но ваш статус пока не обновится! Мы решим эту проблему на следующем этапе.

      Подписаться на события, отправленные сервером

      Прежде чем начать прослушивать события, нам нужна функция, обрабатывающая такие события, как сообщения. Поскольку позже мы будем подключаться к событиям типа «сообщения», мы можем реализовать её соответствующим образом. Всё, что делает функция, — это принимает event.data, преобразует его в объект и вызывает addChatLine.

      const onMessage = (event) => {
      const chatLine = JSON.parse(event.data)
      addChatLine(chatLine)
      }
      

      Для получения событий, отправляемых сервером, мы создаём объект класса EventSource с нашим локальным адресом. Затем добавляем прослушиватель событий для этого типа сообщения. Затем оборачиваем его в хук useEffect (это гарантирует, что когда компонент Он монтируется, инициализируется источник событий, а затем закрывается после монтирования).

      useEffect(() => {
      let source = new EventSource('http://localhost:4000/listen')
      source.addEventListener('message', onMessage)
      setEventSource(source)
      return () => { source.close() }
      }, [])

      Компонент В конечном итоге это выглядит так:

      import React, { useEffect, useState } from 'react'
      import ChatLineHolder from './ChatLineHolder'
      import ChatInput from './ChatInput'
      const App = () => {
      const [chatLines, setChatLines] = useState([])
      const [eventSource, setEventSource] = useState(null)
      const [name] = useState(generateRandomName())
      const addChatLine = (chatLine) => {
      setChatLines(chatLines => [...chatLines, chatLine])
      }
      const onMessage = (event) => {
      const chatLine = JSON.parse(event.data)
      addChatLine(chatLine)
      }
      useEffect(() => {
      let source = new EventSource("http://localhost:4000/listen")
      source.addEventListener('message', onMessage)
      setEventSource(source)
      return () => { source.close() }
      }, [])
      const onSend = (message) => {
      fetch(
      `http://localhost:4000/say`,
      {
      headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      },
      method: "post",
      mode: 'no-cors',
      body: `name=${name}&message=${message}`,
      })
      }
      return (
      <div className='chat-app'>
      <h2>Chatting as {name}</h2>
      <ChatLineHolder lines={chatLines} />
      <ChatInput onSend={onSend} />
      </div>
      )
      }
      export default App

      Результат

      Теперь вы можете открыть свою страницу в двух вкладках и общаться с двумя альтер-эго! Вы также можете дважды смонтировать компонент App (изменяя index.js), поскольку у каждого экземпляра своё состояние.

  • Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может понравиться