|
@@ -0,0 +1,123 @@
|
|
|
+# Redux Chat Homework.
|
|
|
+
|
|
|
+Допилить чат используя **Redux**.
|
|
|
+
|
|
|
+## `chat`
|
|
|
+
|
|
|
+Ветка `chat` и редьюсер `chatReducer` предназначены для работы части
|
|
|
+хранилища, ответственного за историю сообщений. Для облегчения
|
|
|
+дочитки сообщений можно использовать `...` в текущий массив. Если не уверены
|
|
|
+что у вас нет "перекрытия" между текущим и приходящим массивами - используйте
|
|
|
+ассоциативный массив по ключу `id` из СУБД вместо массива сообщений.
|
|
|
+
|
|
|
+### `chatReducer`
|
|
|
+
|
|
|
+Должен поддерживать следующие `action.type`:
|
|
|
+
|
|
|
+- `CHAT_CLEAR` - очищает хранилище при смене чатрума. Это же состояние должно быть в начале работы.
|
|
|
+- `CHAT_MESSAGES` - добавляет новые сообщения в хранилище. В объект действия нужно добавить результат промиса получения сообщений с сервера.
|
|
|
+
|
|
|
+### `<Chat />`
|
|
|
+
|
|
|
+Компонент `Chat` должен быть подписан на ветвь `chat` хранилища используя `<Provider>` и `connect`.
|
|
|
+Можете создать компонент `ChatConnected` или перезаписать `Chat`:
|
|
|
+
|
|
|
+```jsx
|
|
|
+Chat = connect(mapStateToProps)(Chat) //Chat component override by redux component-wrapper
|
|
|
+```
|
|
|
+
|
|
|
+Создайте функцию `mapStateToProps`, которая создает пропс `messages` из ветви `chat`. Используйте `map` по `this.messagesБЛАБЛА` для формирования
|
|
|
+массива `<ChatMessage ... />`.
|
|
|
+
|
|
|
+### `setInterval`
|
|
|
+
|
|
|
+Куда-нибудь (в `componentWillMount` компонента `Chat` или глобально) вставьте `setInterval` который будет посылать запрос за сообщениями
|
|
|
+и складывать их в хранилище используя `dispatch({type: 'CHAT_MESSAGES', данные)` или **actionCreator**. Перед запросом
|
|
|
+спросите у `store` текущий чатрум используя метод `getState()`.
|
|
|
+
|
|
|
+### `messageId`
|
|
|
+
|
|
|
+Можно пока 0, но лучше сделать в ветви `chat` хранилища ключ для этих целей.
|
|
|
+
|
|
|
+### Очистка чата
|
|
|
+
|
|
|
+Должна выполняться по действию `CHAT_CLEAR` (а также `CHATROOM_SET`). Может обнулять `messageId` при его наличии.
|
|
|
+
|
|
|
+## `chatRooms`
|
|
|
+
|
|
|
+Эта ветвь нужна для хранения списка комнат. Достаточно действия `ROOMS` которое выполнится
|
|
|
+при чтении списка комнат (в `then` соответственного `fetch`)
|
|
|
+
|
|
|
+## `currentChatRoom`
|
|
|
+
|
|
|
+Эта ветвь с единственным значением должна хранить `id` текущего чатрума. Редьюсер предусматирвает
|
|
|
+единственный **action** `CHATROOM_SET`. Этот же тип действия должен вызывать очистку
|
|
|
+сообщений чата в соседнем редьюсере.
|
|
|
+
|
|
|
+### `<ChatRooms />`
|
|
|
+
|
|
|
+Просто подписать на ветвь `chatRooms`. Пока оно `undefined` - пусть пишет `Loading`. После
|
|
|
+получения массива - формировать `<select ...>`, и послать инициирующий `CHATROOM_SET` в хранилище.
|
|
|
+
|
|
|
+#### `onChange`
|
|
|
+
|
|
|
+Создать **actionCreator** `actionChatRoomSet(id)`, который будет создавать действие с `type` `CHATROOM_SET` и значением `id` для отправки в хранилище.
|
|
|
+Передать этот **actionCreator** в `mapDispatchToProps` компонента `<ChatRooms />`.
|
|
|
+Вызывать `this.props.actionChatRoomSet(evt.target.value)` при событии `onChange` в `<select />`
|
|
|
+
|
|
|
+## `newMessage`
|
|
|
+
|
|
|
+Эта ветвь может хранить сообщение или хотя бы состояние отправки текущего сообщения. Например:
|
|
|
+- type `MESSAGE_SENDING` и соответствующее состояние в хранилище (типа `status = "MESSAGE_SENDING"`)
|
|
|
+- type `MESSAGE_SENT`
|
|
|
+- type `MESSAGE_FAIL`
|
|
|
+
|
|
|
+### `<Inputs />`
|
|
|
+
|
|
|
+Компонент подписывается на ветвь `newMessage` для того, что бы отслеживать процесс отправки
|
|
|
+и заблокировать поля ввода на время передачи данных. После успешной отправки
|
|
|
+почистить поле сообщения, после неудачной - оставить текст неизменным.
|
|
|
+
|
|
|
+В компонент через `mapDispatchToProps` передать следующие **actionCreator**-ы:
|
|
|
+- `actionMessageSending` - вызывать при отправке сообщения
|
|
|
+- `actionMessageSent` - `then`, успех
|
|
|
+- `actionMessageFail` - `then`, catch
|
|
|
+
|
|
|
+#### `render`
|
|
|
+
|
|
|
+- При `this.props.newMessage.status == 'MESSAGE_SENDING'` - включаем `disabled` у полей ввода;
|
|
|
+- При `MESSAGE_SENT` - разблокируем поля ввода, чистим поле сообщения;
|
|
|
+- При `MESSAGE_FAIL` - разблокируем поля ввода, делаем их красными, не чистим сообщение для повторной отправки.
|
|
|
+
|
|
|
+
|
|
|
+## Отладка
|
|
|
+
|
|
|
+### `subscribe`
|
|
|
+
|
|
|
+```jsx
|
|
|
+store.subscribe(() => console.log(store.getState()))
|
|
|
+```
|
|
|
+
|
|
|
+расскажет вам всё, что твориться в хранилище.
|
|
|
+
|
|
|
+### `connect`
|
|
|
+
|
|
|
+Что бы отладить конфигурацию, переданную в `connect`, используйте `console.log`:
|
|
|
+
|
|
|
+```jsx
|
|
|
+...
|
|
|
+render(){
|
|
|
+ console.log(this.props)
|
|
|
+ return (
|
|
|
+ ....
|
|
|
+ )
|
|
|
+}
|
|
|
+...
|
|
|
+```
|
|
|
+
|
|
|
+Если у вас там все правильно, то вы увидите ключи из объекта, возвращаемого `mapStateToProps` и названия **actionCreator**(ов) из `mapDispatchToProps`.
|
|
|
+
|
|
|
+### `props`
|
|
|
+
|
|
|
+И наоборот, вы всегда можете просимулировать **Redux**, если явно пропишите исходному компоненту параметры через `props` вместо использования `connect`
|
|
|
+и хранилища.
|