Автор оригинала: Nathan Sebhastian.
Крючки – это новое дополнение в реакции 16.8, которые позволяют нам использовать состояние и другие функции реагирования без записи класса.
«Я могу построить полностью функциональное приложение без классов?» Я слышу, как вы спросите. Да, ты можешь! И в этом руководстве я покажу вам, как.
Хотя некоторые учебники будут сосредоточены на крючках в изоляции с «составом» примерами, в этом руководстве, я хочу показать вам, как построить приложение по реальному миру.
В конце концов, у вас будет что-то подобное:
Как вы следуете, вы узнаете, как использовать вновь введенные Уместите и Useffect Крючки, которые позволяют нам управлять состоянием и жизненным циклом функционировать более чисто.
Конечно, если вы предпочитаете прыгать прямо в код, вы можете увидеть полный репозиторий на Github Отказ
Комик
Вместо того, чтобы построить наш собственный чат, мы будем использовать Аккаунт Песочницы Comethat Отказ
В двух словах CHETCHAT является API, который позволяет нам создавать связь связи, как общение в реальном времени. В нашем случае мы будем использовать модуль NPM для подключения и начните передавать сообщения в режиме реального времени.
Со всем тем, что сказано, перед подключением к Comethat мы должны сначала создать приложение Comethat (пожалуйста, подпишите для A Free Free Comethat Account для начала создания приложения).
Теперь, отправляйтесь на приборную панель и введите имя приложения – я позвонил шахты «React-Chat-Cloots». Нажмите +, чтобы создать свое приложение:
Создание приложения с Chetchat
После создания, сверните в ваше недавно созданное приложение и нажмите API Ключ Отказ Отсюда скопируйте свои автоматически сгенерированные Авторизионный ключ :
Получить API Cometchat
Нам понадобится это на следующем шаге.
Настройка реакции
С нашим приложением 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
);
};
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?
Если это выглядит как много кода, ну, это так! Но все, что мы делаем здесь, – это рендеринг наших друзей ( 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. Большая помощь. Проверьте это здесь !
Первоначально опубликовано в https://www.com.comethat.com.