Рубрики
Без рубрики

Создание приложения чата с реактивными крючками, прагматичным примером

Крючки – это новое дополнение в реакции 16.8, которые позволяют нам использовать состояние и другие функции реагирования без записи класса.

Автор оригинала: Nathan Sebhastian.

Крючки – это новое дополнение в реакции 16.8, которые позволяют нам использовать состояние и другие функции реагирования без записи класса.

«Я могу построить полностью функциональное приложение без классов?» Я слышу, как вы спросите. Да, ты можешь! И в этом руководстве я покажу вам, как.

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

В конце концов, у вас будет что-то подобное:

rage_hooks_img.gif.

Как вы следуете, вы узнаете, как использовать вновь введенные Уместите и Useffect Крючки, которые позволяют нам управлять состоянием и жизненным циклом функционировать более чисто.

Конечно, если вы предпочитаете прыгать прямо в код, вы можете увидеть полный репозиторий на Github Отказ

Комик

Вместо того, чтобы построить наш собственный чат, мы будем использовать Аккаунт Песочницы Comethat Отказ

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

Со всем тем, что сказано, перед подключением к Comethat мы должны сначала создать приложение Comethat (пожалуйста, подпишите для A Free Free Comethat Account для начала создания приложения).

Теперь, отправляйтесь на приборную панель и введите имя приложения – я позвонил шахты «React-Chat-Cloots». Нажмите +, чтобы создать свое приложение:

Создание приложения с Chetchat

image_preview.png.png.png

После создания, сверните в ваше недавно созданное приложение и нажмите API Ключ Отказ Отсюда скопируйте свои автоматически сгенерированные Авторизионный ключ :

Получить API Cometchat

image_preview (1) .png

Нам понадобится это на следующем шаге.

Настройка реакции

С нашим приложением Comethat на месте откройте свою командную строку и инициализируйте реагирование с помощью NPX и Create-React-App :

npx create-react-app cometchat-react-hooks

Однажды Create-React-App Закончил спиннинг, откройте вновь созданную папку и установите следующие модули:

cd cometchat-react-hooks
npm install @cometchat-pro/chat bootstrap react-md-spinner react-notifications

Нам понадобится эти зависимости, чтобы завершить наше приложение.

Пока мы здесь, мы также должны удалить все файлы внутри SRC Каталог:

rm src

Иногда эта котельная полезная, но сегодня я заинтересован, чтобы начать с нуля.

Итак, в духе начиная с нуля, создайте новый файл с именем SRC/config.js Файл и заполните свои учетные данные Comethat:

// src/config.js
    
const config = {
  appID: '{Your CometChat Pro App ID here}',
  apiKey: '{Your CometChat Pro Api Key here}',
};
    
export default config;

Через этот файл мы можем удобно получить доступ к нашим учетным данным по всему миру.

Далее написать новый SRC/index.js файл:

import React from 'react';
import ReactDOM from 'react-dom';
import {CometChat} from '@cometchat-pro/chat';
import App from './components/App';
import config from './config';
    
CometChat.init(config.appID);
    
ReactDOM.render(, document.getElementById('root'));

Это точка входа для нашего приложения React. При загружении мы сначала инициализируем CHETCHAT перед рендером нашего Приложение Компонент, который мы определимся в мгновение.

Настройка наших компонентов

Наше приложение будет иметь три примечательных компонента, а именно Приложение , Вход и Чат Отказ

Для размещения наших компонентов создайте нефтевую папку с именем Компоненты И внутри него сами компоненты:

mkdir components && cd components
touch App.js Login.js Chat.js

App.js:

import React from 'react';
    
const App = () => {
  return (
    
This is the App component
); }; export default App;

Login.js:

import React from 'react';
    
const Login = () => {
  return (
    
This is the Login component
); }; export default App;

Chat.js.

import React from 'react';
    
const Chat = () => {
  return (
    
This is the Chat component
); }; export default App;

Если вы хотите, вы можете запустить приложение с NPM начать И соблюдайте текст « Это компонент приложения » текст.

Конечно, это просто заполнитель. Строительство Приложение Компонент является предметом нашего следующего раздела.

Создание компонента приложения

Хорошо, время серьезно относиться к крючкам.

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

Для начала заменить app.js с:

import React, {useState} from 'react';
import 'bootstrap/dist/css/bootstrap.css';
import 'react-notifications/lib/notifications.css';
import './App.css';
import {NotificationContainer} from 'react-notifications';
import Login from './Login';
import Chat from './Chat';
    
const App = () => {
  const [user, setUser] = useState(null);
  const renderApp = () => {
    // Render Chat component when user state is not null
    if (user) {
      return ;
    } else {
      return ;
    }
  };
  return (
    
{renderApp()}
); }; export default App;

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

Как вы можете видеть, мы впервые импортируем вновь представленные Уместите Крюк, который является функцией:

import React, {useState} from 'react';

Уместите Может использоваться для создания государственной собственности.

Дать вам представление, до Уместите Крюк, вы могли бы написать что-то вроде:

this.state = { user: null };
    
setState({ user: { name: "Joe" }})

С крючками, (более или менее) эквивалентный код выглядит как:

const [user, setUser] = useState(null);
    
setUser({ user: { name: "Joe" }})

Важная разница вот что при работе с Это и SetState Вы работаете со всем государственным объектом. С Уместите Крюк, вы работаете с индивидуальной государственной собственностью. Это часто приводит к чищему коду.

Уместите Принимает один аргумент, который является исходным состоянием, а оперативно возвращает два значения, а именно то же самое начальное состояние (в этом случае, пользователь ) и функция, которую можно использовать для обновления состояния (в этом случае, setuser ). Здесь мы передаем начальное состояние null Но любой тип данных в порядке.

Если что все звуки достаточно легко, это может быть так же хорошо!

Там нет необходимости чрезмерно подумать Уместите Потому что это просто другой интерфейс для обновления состояния – фундаментальная концепция, с которой я уверен, что вы знакомы.

С нашим начальным государством на месте, от RenderApp Мы можем условно рендер Чат или Вход В зависимости от того, вошел ли пользователь (другими словами, если пользователь был установлен):

const renderApp = () => {
  // Render Chat component when user state is not null
  if (user) {
    return ;
  } else {
    return ;
  }
};

RenderApp называется из оказывать Функция, где мы также оказываем нашу NotifcationContainer Отказ

Если вы Sharp, вы могли бы заметить, что мы импортировали файл CSS с именем App.css, но на самом деле еще не создал его. Давайте сделаем это дальше.

Создайте новый файл с именем App.csss:

.container {
  margin-top: 5%;
  margin-bottom: 5%;
}
    
.login-form {
  padding: 5%;
  box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 9px 26px 0 rgba(0, 0, 0, 0.19);
}
    
.login-form h3 {
  text-align: center;
  color: #333;
}
    
.login-container form {
  padding: 10%;
}
    
.message {
  overflow: hidden;
}
    
.balon1 {
  float: right;
  background: #35cce6;
  border-radius: 10px;
}
    
.balon2 {
  float: left;
  background: #f4f7f9;
  border-radius: 10px;
}

.container {
  margin-top: 5%;
  margin-bottom: 5%;
}
    
.login-form {
  padding: 5%;
  box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 9px 26px 0 rgba(0, 0, 0, 0.19);
}
    
.login-form h3 {
  text-align: center;
  color: #333;
}
    
.login-container form {
  padding: 10%;
}
    
.message {
  overflow: hidden;
}
    
.balon1 {
  float: right;
  background: #35cce6;
  border-radius: 10px;
}
    
.balon2 {
  float: left;
  background: #f4f7f9;
  border-radius: 10px;
}

Создание компонента входа

В качестве напоминания наш компонент входа будет выглядеть так:

Следовать, заменить Login.js с участием:

import React, {useState} from 'react';
import {NotificationManager} from 'react-notifications';
import {CometChat} from '@cometchat-pro/chat';
import config from '../config';
    
const Login = props => {
  const [uidValue, setUidValue] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
    
  return (
    

Login to Awesome Chat

setUidValue(event.target.value)} />
); }; export default Login;

Вот, мы используем Уместите Для создания двух свойств состояния: UidValue и Опустить Отказ

До крючка мы могли бы написать что-то вроде:

this.setState({
  uidValue: '',
  isSubmitting: false
})

Однако это требовалось бы класс. Здесь мы используем функциональный компонент – аккуратный!

В той же функции (до того, как return заявление), создайте Handlesubmit Функция, которая должна называться, когда форма представлена:

const handleSubmit = event => {
  event.preventDefault();
  setIsSubmitting(true);
  CometChat.login(uidValue, config.apiKey).then(
    User => {
      NotificationManager.success('You are now logged in', 'Login Success');
      console.log('Login Successful:', {User});
      props.setUser(User);
    },
    error => {
      NotificationManager.error('Please try again', 'Login Failed');
      console.log('Login failed with exception:', {error});
      setIsSubmitting(false);
    }
  );
};

Здесь мы используем setissubmitting Функция возвращена Уместите Отказ После набора форм будет отключен.

Затем мы называем Comethat.login Чтобы аутентифицировать пользователя, использующий наш ключ. В производственном приложении Chetchat рекомендует выполнять собственную логику аутентификации.

Если логин успешен, мы называем Props.SetUser Отказ

В конечном итоге, Props.SetUser Обновляет значение Пользователь в нашем Приложение Компонент и – как следует ожидать, когда вы обновляете состояние в React – приложение повторно отображается. На этот раз Пользователь Будет правдой и так, App.renderapp Функция, которую мы проверили ранее, сделают Чат составная часть.

Создание компонента чата

Наше Чат Компонент имеет много ответственности. На самом деле, это самый важный компонент в нашем приложении!

От Чат Компонент, пользователю необходимо:

  • Выберите друга, с которым можно пообщаться
  • Увидеть их недавнюю историю сообщений
  • Отправить новые сообщения
  • Получать ответы в режиме реального времени

Как вы можете себе представить, это потребует от нас, чтобы обработать много государства. Я, например, не могу думать о лучшем месте, чтобы практиковать наши новые знания о Уместите крюк! Но как упомянуто в моем вступлении, Уместите Это только один крюк, на котором мы будем смотреть сегодня. В этом разделе мы также будем исследовать Useffect крюк.

Я могу сказать вам сейчас, Useffect заменяет ComponentDidmount , ComponentDidupdate и ComponentWillunmount Функции жизненного цикла, которые вы, вероятно, придумаете.

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

Useffect немного более нюанс, чем Уместите Но когда в комплекте с примером я уверен, что вы поймете это.

Useffect Принимает два аргумента, а именно функция для выполнения (например, функция для получения исходных данных) и необязательный массив недвижимости состояния для наблюдения. Если какое-либо свойство, упомянутое в этом массиве, обновляется, аргумент функции снова выполняется. Если пропущено пустая массив, вы можете быть уверены, что аргумент функции будет запущен только один раз во всей жизни компонента.

Давайте начнем с отображения необходимого состояния. Этот компонент будет иметь 6 государственных свойств:

  • друзья Чтобы сохранить список пользователей, доступных для чата
  • Выбранная друга – Чтобы сохранить текущий выбранный друг для чата
  • Чат – Чтобы сохранить массив сообщений чата, отправляемых и полученных между друзьями
  • Chatisloading – Чтобы указать, когда приложение получает предыдущие чаты с сервера CHETCHAT
  • дружелюбие – Чтобы указать, когда приложение приобретает все друзья, доступные для чата
  • сообщение – Для нашего сообщения ввода ввода компонент

Возможно, лучший способ освоить Useffect это увидеть в действии. Не забудьте импортировать Useffect и обновить Chat.js :

import React, {useState, useEffect} from 'react';
import MDSpinner from 'react-md-spinner';
import {CometChat} from '@cometchat-pro/chat';
    
const MESSAGE_LISTENER_KEY = 'listener-key';
const limit = 30;
    
const Chat = ({user}) => {
  const [friends, setFriends] = useState([]);
  const [selectedFriend, setSelectedFriend] = useState(null);
  const [chat, setChat] = useState([]);
  const [chatIsLoading, setChatIsLoading] = useState(false);
  const [friendisLoading, setFriendisLoading] = useState(true);
  const [message, setMessage] = useState('');  
};
    
export default Chat;

Когда наш Чат Компонент установлен, мы должны сначала Привлечь пользователей Доступно для чата. Для этого мы можем использовать Useffect Отказ

В пределах Чат Компонент без гражданства, звонок Useffect как это:

useEffect(() => {
  // this useEffect will fetch all users available for chat
  // only run on mount
    
  let usersRequest = new CometChat.UsersRequestBuilder()
    .setLimit(limit)
    .build();
    usersRequest.fetchNext().then(
      userList => {
        console.log('User list received:', userList);
        setFriends(userList);
        setFriendisLoading(false);
      },
      error => {
        console.log('User list fetching failed with error:', error);
      }
    );
    
    return () => {
      CometChat.removeMessageListener(MESSAGE_LISTENER_KEY);
      CometChat.logout();
    };
    
}, []);

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

То, что я еще не упомянул, это то, что вы можете вернуть функцию из Useffect Быть автоматически вызываться путем реагирования, когда компонент не размонтируется. Другими словами, это ваш ComponentWillunmount функция.

В нашем ComponentWillunmount -Еквивалентная функция, мы называем RemoveMessageListener и Выход из системы Отказ

Далее, давайте напишем Возвращение Заявление Чат составная часть:

return (
  

Friend List

Who you gonna chat with?

{ setMessage(event.target.value); }} value={message} placeholder='Type a message...' />
);

Если это выглядит как много кода, ну, это так! Но все, что мы делаем здесь, – это рендеринг наших друзей ( FrameList ) и Box Chat ( Chatbox ), в стиле загрузки.

Мы на самом деле не определили наши Друзья или Чатбокс Компоненты, так что давайте сделаем это сейчас.

В том же файле создайте компоненты под названием Чатбот и Список друзей :

const ChatBox = props => {
  const {chat, chatIsLoading, user} = props;
  if (chatIsLoading) {
    return (
      
); } else { return (
{chat.map(chat => (
{chat.text}
))}
); } }; const FriendList = props => { const {friends, friendisLoading, selectedFriend} = props; if (friendisLoading) { return (
); } else { return (
    {friends.map(friend => (
  • props.selectFriend(friend.uid)}> {friend.name}
  • ))}
); } };

С нашей Друзья и Чатбокс Компоненты на месте, наш UI более или менее полный, но нам все еще нужен способ отправлять и получать сообщения в режиме реального времени.

Создание функции выбора

В вышеуказанном Друзья Компонент, мы ссылались на функцию под названием Выбор подруги Чтобы быть вызванным, когда пользователь нажимает на одном из имени в списке, но мы еще не определили его.

Мы можем написать эту функцию в Чат Компонент (до возврата return ) и пропустите его вниз Дружественный список как опоры:

const selectFriend = uid => {
  setSelectedFriend(uid);
  setChat([]);
  setChatIsLoading(true);
};

Когда выбран друг, мы обновляем наше состояние:

  • Выбранная друга обновляется с UID нового друга.
  • Чат Снова устанавливается, поэтому сообщения от предыдущего друга не смешиваются с новым.
  • Chatisloading установлено значение true, так что спиннер заменит пустую коробку чата

Работа с использованием USEFFECT на выделенном настроении

Когда выбрано новое преобразование, нам нужно инициатировать преобразование. Это означает получать старые сообщения и подписаться на новые в режиме реального времени.

Для этого мы используем использование Useffect Отказ В Чат Компонент (и, как обычно, до того, как return ):

useEffect(() => {
  // will run when selectedFriend variable value is updated
  // fetch previous messages, remove listener if any
  // create new listener for incoming message
    
  if (selectedFriend) {
    let messagesRequest = new CometChat.MessagesRequestBuilder()
      .setUID(selectedFriend)
      .setLimit(limit)
      .build();
    
    messagesRequest.fetchPrevious().then(
      messages => {
        setChat(messages);
        setChatIsLoading(false);
        scrollToBottom();
      },
      error => {
        console.log('Message fetching failed with error:', error);
      }
    );
    
    CometChat.removeMessageListener(MESSAGE_LISTENER_KEY);
    
    CometChat.addMessageListener(
      MESSAGE_LISTENER_KEY,
      new CometChat.MessageListener({
        onTextMessageReceived: message => {
          console.log('Incoming Message Log', {message});
          if (selectedFriend === message.sender.uid) {
            setChat(prevState => [...prevState, message]);
          }
        },
      })
    );
  }
}, [selectedFriend]);

Проходя [Выбранная друга] массив в Useffect Второй аргумент, мы гарантируем, что функция выполняется каждый раз Выбранная друга обновляется. Это очень элегантно.

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

Отправка нового обработчика сообщений

Чтобы отправить новые сообщения, мы можем подключить нашу форму до Comethat.sendmessage функция. В Чатбокс Функция, создать функцию под названием Handlesubmit :

const handleSubmit = event => {
  event.preventDefault();
  let textMessage = new CometChat.TextMessage(
    selectedFriend,
    message,
    CometChat.MESSAGE_TYPE.TEXT,
    CometChat.RECEIVER_TYPE.USER
  );
  CometChat.sendMessage(textMessage).then(
    message => {
      console.log('Message sent successfully:', message);
      setChat([...chat, message]);
    },
    error => {
      console.log('Message sending failed with error:', error);
    }
  );
  setMessage('');
};

Это уже упоминается от JSX, который вы скопировали ранее.

Когда новое сообщение успешно отправлено, мы называем Сетчат и обновить значение Чат Состояние с последним сообщением.

Создание Scrolltobottom Функция

Наше Чат Компонент выглядит мило, кроме одного: когда есть куча сообщений в Чатбокс Пользователь должен вручную прокрутить дону, чтобы увидеть последние сообщения.

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

const scrollToBottom = () => {
  let node = document.getElementById('ccChatBoxEnd');
  node.scrollIntoView();
};

Затем запустите эту функцию, когда предыдущие сообщения установлены в состояние:

messagesRequest.fetchPrevious().then(
  messages => {
    setChat(messages);
    setChatIsLoading(false);
    scrollToBottom();
  },
  error => {
    console.log('Message fetching failed with error:', error);
  }
);

Заключение

Если вы сделали это так далеко, вы успешно создали приложение чата, работающие на Comethat и крючки. Высокие пять 👋🏻!

С этим опытом под вашим поясом я уверен, что вы можете начать ценить «шумиху» вокруг крючков.

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

И во всяком истине мы только коснулись поверхности. С некоторыми руководством от Официальная документация, Вы даже можете создать свои собственные крючки!

P.S: Если вы изо всех сил пытаетесь научиться реагировать, вы можете найти React Reptived. Большая помощь. Проверьте это здесь !

CTA-RACT-DISTLILD-D1A3DC470CBFAFB1C7D56C72F262649E.jpg

Первоначально опубликовано в https://www.com.comethat.com.