Я работаю над приложением чата, которое отображает сообщение чата (компонент React), как только пользователь отправляет его, нажимая Enter
:
![enter image description here](https://i.stack.imgur.com/MJXLd.png)
![enter image description here](https://i.stack.imgur.com/S6thO.png)
Здесь, после ввода ABC
и нажатия Enter
, состояние компонента React обновляется сразу же, и сообщение отображается во избежаниемедленный пользовательский интерфейс.
Затем выполняется запрос AJAX.AJAX отправляет сообщение на сервер, который, в свою очередь, создает новый чат, если chat_id
равно 0 (первое сообщение чата), сохраняет сообщение и возвращает идентификатор вновь созданного чата.На этом этапе чат обновляется с идентификатором, возвращенным сервером.Ниже приведен фрагмент кода:
class ChatApp extends React.Component {
// ...
constructor(props) {
super(props)
this.state = {
currentChat: {
id: 0, // 0 means "this is a new chat"
messages: [],
// ...
}
}
}
handleSendMessage(message) {
this.setState((prevState) => {
const pendingCurrentChat = {
...prevState.currentChat,
messages: prevState.currentChat.messages.concat([{
message
}])
}
return {
currentChat: pendingCurrentChat
}
}, () =>
this.setState((state) => {
const currentChat = state.currentChat
const currentChatId = currentChat.id
// AJAX call starts here:
const params = {
act: 'handleSendMessage',
message: message,
chat_id: currentChatId
}
this.POST(params, JSONResponseData =>
this.setState((prevState) => {
const chatId = JSONResponseData.chat_id
const currentChat = {
...prevState.currentChat,
id: chatId
}
const newState = {
currentChat
}
return newState
})
)
// No state change here.
return null
})
)
}
// ...
}
Проблема этого подхода заключается в том, что если чат новый (currentChat.id == 0
), а пользователь отправляет кучу сообщений, набирая и нажимая Enter
быстро возникает состояние гонки, и некоторые запросы AJAX с перекрытием chat_id: 0
приводят к созданию нескольких чатов на стороне сервера:
![enter image description here](https://i.stack.imgur.com/y2lJI.png)
Здесь у меня естьнабрал a
и быстро войти, и я закончил тем, что на стороне сервера было создано более одного чата, потому что было сделано несколько запросов с 0
, установленным на *1034*.
Как я могу убедиться, что только первыйсообщение чата отправляется на сервер с chat_id: 0
без возникновения состояния гонки, если пользователь быстро набирает текст?
Я могу думать только о:
- Генерация идентификаторовна стороне клиента (возможно, UUID), который затем отправляется на сервер.Я действительно не хочу позволить пользователю подождать, пока первый AJAX завершит работу, прежде чем рендерить первое сообщение;
- Создать новый чат, прежде чем разрешить пользователю отправлять сообщение.Тем не менее, таким образом я буду использовать идентификаторы на сервере, даже если пользователь не может отправить первое сообщение;
Например, Messenger Facebook имеет такое поведение, которое я ищу: когда вы отправляете сообщение, онокак только они нажимают Enter
, как они справляются с этим?Глядя на вкладку сети, кажется, что они создают идентификатор заранее, но я не уверен:
![enter image description here](https://i.stack.imgur.com/QawDQ.png)
Как бы вы справились с этимс точки зрения UI / UX и сохранности данных на стороне сервера?