Допилить чат используя Redux.
chat
Ветка chat
и редьюсер chatReducer
предназначены для работы части
хранилища, ответственного за историю сообщений. Для облегчения
дочитки сообщений можно использовать ...
в текущий массив. Если не уверены
что у вас нет "перекрытия" между текущим и приходящим массивами - используйте
ассоциативный массив по ключу id
из СУБД вместо массива сообщений.
chatReducer
Должен поддерживать следующие action.type
:
CHAT_CLEAR
- очищает хранилище при смене чатрума. Это же состояние должно быть в начале работы.CHAT_MESSAGES
- добавляет новые сообщения в хранилище. В объект действия нужно добавить результат промиса получения сообщений с сервера.<Chat />
Компонент Chat
должен быть подписан на ветвь chat
хранилища используя <Provider>
и connect
.
Можете создать компонент ChatConnected
или перезаписать Chat
:
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
Эта ветвь может хранить сообщение или хотя бы состояние отправки текущего сообщения. Например:
MESSAGE_SENDING
и соответствующее состояние в хранилище (типа status = "MESSAGE_SENDING"
)MESSAGE_SENT
MESSAGE_FAIL
<Inputs />
Компонент подписывается на ветвь newMessage
для того, что бы отслеживать процесс отправки
и заблокировать поля ввода на время передачи данных. После успешной отправки
почистить поле сообщения, после неудачной - оставить текст неизменным.
В компонент через mapDispatchToProps
передать следующие actionCreator-ы:
actionMessageSending
- вызывать при отправке сообщенияactionMessageSent
- then
, успехactionMessageFail
- then
, catchrender
this.props.newMessage.status == 'MESSAGE_SENDING'
- включаем disabled
у полей ввода;MESSAGE_SENT
- разблокируем поля ввода, чистим поле сообщения;MESSAGE_FAIL
- разблокируем поля ввода, делаем их красными, не чистим сообщение для повторной отправки.subscribe
store.subscribe(() => console.log(store.getState()))
расскажет вам всё, что творится в хранилище.
connect
Что бы отладить конфигурацию, переданную в connect
, используйте console.log
:
...
render(){
console.log('<Component /> Props: ',this.props)
return (
....
)
}
...
Если у вас там все правильно, то вы увидите ключи из объекта, возвращаемого mapStateToProps
и названия actionCreator(-ов) из mapDispatchToProps
.
props
И наоборот, вы всегда можете просимулировать Redux, если явно пропишите исходному компоненту параметры через props
(используя "атрибуты тэга" JSX) вместо использования connect
и хранилища.