Здравствуйте.
У меня такая проблема, при изменении состояния в redux, не происходит рендер компонента который этот state использует.
Компонент Sidebar:import { getConversations } from '../actions/conversations';
class Sidebar extends Component {
showChats(thiss){
return this.props.dialogs.map(function(dialog, key){
if (!dialog.disable) {
return (
<NavLink key={key} to='/dialogs'><SidebarChat dialog={dialog} /></NavLink>
);
}
});
}
componentDidMount(){
this.props.getConversations();
}
render() {
console.log(this.props.dialogs);
if (this.props.dialogs) {
return (
<div className='sidebar'>
<div className='sidebar__content'>
<div className='sidebar__head'></div>
<SidebarChatGroup chatName='Общий'>
{this.showChats(this)}
</SidebarChatGroup>
</div>
<div className='sidebar__bg'></div>
</div>
);
}
else {
return (
<div className='sidebar'>
<div className='sidebar__content'>
<div className='sidebar__head'></div>
<Preloader />
</div>
<div className='sidebar__bg'></div>
</div>
)
}
}
}
function mapStateToProps(state){
return {
dialogs: state.conversations[0]
};
}
const mapDispatchToProps = (dispatch) => {
return {
getConversations: (url) => dispatch(getConversations(url))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);
В нем при вызове
getConversations(); рендер происходит нормально, но при клике на кнопку (функции
openDialog и
disableDialog) в компоненте
SidebarChat должен изменяться state и соответственно заново рендерится компонент
Sidebar
Но этого не происходит. Почему?
Компонент
SidebarChat:import { openConversation, closeConversation } from '../actions/conversations';
class SidebarChat extends Component {
openDialog(){
// проверка на открыт ли диалог при клике на диалог в сайдбаре
// если открыт, то false, если нет, то открываем
if (this.props.dialog.active) {
return false;
} else {
this.props.openDialog(this.props.dialog.id);
}
}
disableDialog() {
this.props.closeDialog(this.props.dialog.id);
};
render() {
return (
<div className={this.props.dialog.active ? "sidebar-chat sidebar-chat__active" : "sidebar-chat" }>
<div className='sidebar-chat__info' onClick={this.openDialog.bind(this)}>
<div className='sidebar-chat__name'>{this.props.dialog.visitor.name ? this.props.dialog.visitor.name : this.props.dialog.visitor.uuid.substr(-10)}</div>
<div className='sidebar-chat__manager'>{this.props.dialog.users.length ? this.props.dialog.users[0].name : 'Нет менеджера'}</div>
<div className='sidebar-chat__border'></div>
</div>
<div className='sidebar-chat__close' onClick={this.disableDialog.bind(this)}></div>
</div>
)
}
}
function mapStateToProps(state){
return {
dialogs: state.dialogs
};
}
const mapDispatchToProps = (dispatch) => {
return {
openDialog: (id) => dispatch(openConversation(id)),
closeDialog: (id) => dispatch(closeConversation(id))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(SidebarChat);
Action:export function closeConversation(id) {
return {
type: 'CLOSE_CONVERSATION',
id: id
};
}
export function openConversation(id) {
return {
type: 'OPEN_CONVERSATION',
id: id
};
}
export function conversationSuccess(chats) {
return {
type: 'CONVERSATIONS_FETCH_DATA_SUCCESS',
chats: chats
};
}
export function getConversations() {
return (dispatch) => {
setTimeout(function() {
hubConnection.invoke('GetActiveConversations', null, null, null);
}, 1500);
hubConnection.on('ApplyActiveConversations', function (conversations) {
// добавляем каждому чату свойства (Активный и открытый\закрытый)
conversations[0].forEach(function(conversation, i){
conversation.active = false;
conversation.disable = false;
});
dispatch(conversationSuccess(conversations));
});
};
}
Reducer:export function conversations(state = [], action) {
if (action.type == 'CONVERSATIONS_FETCH_DATA_SUCCESS') {
return action.chats;
}
else if (action.type == 'OPEN_CONVERSATION') {
let newState = [...state];
newState[0].forEach(function(dialog, i){
if (dialog.id == action.id) {
dialog.active = true;
}
});
return newState;
}
else if (action.type == 'CLOSE_CONVERSATION') {
let newState = [...state];
newState[0].forEach(function(dialog, i){
if (dialog.id == action.id) {
dialog.active = false;
}
});
console.log(newState);
return newState;
}
else {
return state;
}
}
Хотя в
reducer console.log(newState) выводит измененный, правильный стэйт.