Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript redux reducer不重新渲染组件_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript redux reducer不重新渲染组件

Javascript redux reducer不重新渲染组件,javascript,reactjs,redux,Javascript,Reactjs,Redux,上下文:我正在尝试创建一个使用react-redux和socket.io的web客户端。设计灵感来自whatsapp,老实说,这只是我用来学习react和redux的一个有趣的小项目 主要的问题是我有一个ActiveChat组件,它不会在商店更改并识别更改时重新呈现。Redux Devtools甚至可以显示状态的差异和变化 已连接该组件: //Redux Mapping for Store and Actions const mapStateToProps = state => { r

上下文:我正在尝试创建一个使用react-redux和socket.io的web客户端。设计灵感来自whatsapp,老实说,这只是我用来学习react和redux的一个有趣的小项目

主要的问题是我有一个ActiveChat组件,它不会在商店更改并识别更改时重新呈现。Redux Devtools甚至可以显示状态的差异和变化

已连接该组件:

//Redux Mapping for Store and Actions
const mapStateToProps = state => {
  return { activeChat: state.activeChat };
};

const mapDispatchToProps = dispatch => {
  return {
    updateActiveChat: chat => dispatch(updateActiveChat(chat))
  }
}

const activeChatConnected = connect(mapStateToProps,mapDispatchToProps)(ActiveChat)


export default activeChatConnected;
我的想法是,我可能无法保持状态的纯净,因为这是我第一次用javascript进行状态不变性的探戈,我希望我能得到社区的帮助

代码在这里可用:(当我试图更好地使用javascript时,总是欢迎反馈)

所讨论的代码片段具体如下:

# src/reducers
const rootReducer = (state = initialState,action) => {
      switch(action.type){
          case SELECT_ACTIVE:
          // Select Active Chat so as to display chat content
            var newActive = Object.assign(state.chats[action.payload.index])
            newActive["index"]= action.payload.index
            return {...state,activeChat:newActive}
          case UPDATE_CHAT:
          // Update store with new Chat Content
            var chats = Object.assign(state.chats)
            chats[state.activeChat.index].chatLogs.concat(action.payload)
            return {...state,chats}
          default:
          return state
      }
}
目前,我已经通过在操作之后设置state来解决这个问题,但这并不理想,因为一旦我使用sockets,setState异步可能会导致某些问题

inputHandler = logs => {
    // Handle Input from chatInput
    var newState = this.state.chatLogs;
    newState.push(logs);
    //Redux Action
    this.props.updateActiveChat(logs)
    console.log(this.state.chatLogs);
    // BAD HOTFIX
    this.setState({});
};
编辑:这是问,所以我将添加到这里。
return{…state,chats}
实际上将结果放入return
{…state,chats:chats}

编辑2:

// actions
import {SELECT_ACTIVE, UPDATE_CHAT} from "../constants/action-types"

export const selectActiveChat = selected => ({type: SELECT_ACTIVE, payload:selected})
export const updateActiveChat = chat => ({type: UPDATE_CHAT, payload:chat})
编辑3:

//activeChat组件的渲染函数

render() {
    if (this.state != null){
      return (
        <div className="column is-8 customColumn-right">
          <div className="topColumn">
            <h1 style={{fontFamily:"Quicksand,sans-serif", fontWeight:"bold", fontSize:"1.1rem"}}> {this.state.chatName} </h1>
            <p style={{fontFamily:"Roboto,sans-serif",marginLeft: "0.75rem",lineHeight:"1"}}> Chat Participants </p>
          </div>
          <ChatContent
            chatLogs={this.props.activeChat.chatLogs}
            isTyping={this.state.isTyping}
          />
          <ChatInput postSubmit={this.inputHandler} />
        </div>
      );
    }
    else {
      return <NoActiveChat/>
    }
  }
  componentWillReceiveProps(newProps){
// Change Props on Receive 
console.log("das new props");
this.setState({
  chatName: newProps.activeChat.chatName,
  chatLogs: newProps.activeChat.chatLogs,
  isTyping: newProps.activeChat.isTyping
})
}
render(){
如果(this.state!=null){
返回(
{this.state.chatName}
聊天参与者

); } 否则{ 返回 } } 组件将接收道具(新道具){ //接收时更换道具 console.log(“das新道具”); 这是我的国家({ chatName:newProps.activeChat.chatName, 聊天记录:newProps.activeChat.chatLogs, isTyping:newProps.activeChat.isTyping }) }
我通过在减速器中以不同的方式执行concat,成功地修复了它。我不明白这是如何改变最终结果的,因为对象仍然在改变,但这似乎已经解决了

而不是:

      case UPDATE_CHAT:
      // Update store with new Chat Content
        console.log("Update chat action executed");
        var chatState = Object.assign({},state)
        chatState.chats[state.activeChat.index].chatLogs.concat(action.payload)
        return {...chatState}
我做到了:

          case UPDATE_CHAT:
          // Update store with new Chat Content
            console.log("Update chat action executed");
            var chatState = Object.assign({},state)
            chatState.chats[state.activeChat.index].chatLogs = chatState.chats[state.activeChat.index].chatLogs.concat(action.payload)
            return {...chatState}
编辑:原来Object.assign()是浅层克隆,这意味着嵌套对象是引用而不是副本。如果你想做深度克隆。您可以使用lodash中的cloneDeep,我意识到这一点,后来我在其他函数中遇到了其他问题

在我的解决方案中,新的案例处理程序如下所示

是我对lodash的进口产品

          case UPDATE_CHAT:
      // Update store with new Chat Content
      console.log("Update chat action executed");
        var chatState = _.cloneDeep(state)
        chatState.chats[state.activeChat.index].chatLogs = chatState.chats[state.activeChat.index].chatLogs.concat(action.payload)
        return {...chatState}

请显示组件中的
updateActiveChat()
操作创建者。并显示组件中的
render()
(或简化版本)。还要提供证据证明您的组件没有按预期呈现。我已经在项目信息中添加了所有git代码。这里有可用的操作:这里有ActiveChat组件:链接很棒,但是如果它们无效,在这里显示完整的代码会很有帮助。(注意:“Complete”意味着足以重现您所询问的行为。“Complete”并不意味着应用程序中的所有代码。)在这种情况下,在这里查看问题中的render()方法以及组件类中任何其他相关部分也会有所帮助。