【问题标题】:ReactJS render function isn't being updatedReactJS 渲染函数没有被更新
【发布时间】:2021-10-24 04:42:48
【问题描述】:

我正在尝试使用 Material UI 制作聊天功能。我创建了一个功能,用户可以在其中发布新的聊天消息,然后通过 reducer 发送这些消息,然后保存在 redux 存储中。此过程按预期工作,但新聊天消息仅在用户刷新页面后出现。我想知道为什么我的渲染功能没有更新。这是主要的聊天画面。

const ChatFunction = (props) => {
  const classes = useStyles();
  const { user } = props;
  const userMessages = props.userMessages || {};
};

const mapStateToProps = (state) => {
  return {
    user: state.user,
    userMessages:
      state.messages &&
      state.messages.find(
        (userMessages) => userMessages.otherUser.username === state.currentMessage
      )
  };
};

export default connect(mapStateToProps, null)(ChatFunction);

postMessage 函数然后通过我的 reducer 并调用我的 reducer 函数以将新消息添加到消息数组中。

export const newMessage = (state, payload) => {
  const { message, sender } = payload;
  return state.map((userMess) => {
    if (userMess.id === message.Id) {
      userMess.messages.push(message);
      userMess.latestMessageText = message.text;
      return userMess;
    } else {
      return userMess;
    }
  });
};

那么,有谁知道为什么不能正确刷新?

【问题讨论】:

  • 你能确认reducer返回了正确的新对象数组吗?我确实在这里看到了一个问题,你改变了 useMess.messages 并推送而不是传播。但这在技术上并不重要,因为您的 .map 将返回一个新的对象数组。
  • reducer 返回包​​含新消息的新数组。一件奇怪的事情是,这在前几天有效,但现在它不再有效。我认为我编写的客户端代码可能存在问题,但现在我想知道这是否是服务器的问题。我只对客户端进行过更改,所以我不明白为什么它会停止工作。
  • mapStateToPropsChatFunction 组件上的条件如何?他们在那里被过滤了吗?我注意到state.userMessagess.find( (userMessages) => userMessages.otherUser.username === state.currentMessage ) 的情况看起来很可疑,所以请验证这是否符合要求。
  • 我重命名了一些变量以便于理解,但我的测试表明它返回了正确的值。
  • 您是否尝试在ChatFunction 中记录props 并查看是否获得了实际刷新的数据?因为当你说它返回正确的值时,它从哪里返回正确的值? reducer 还是 mapStateToProps?

标签: javascript reactjs react-redux material-ui


【解决方案1】:

当您直接压入用户的messages 数组并改变其他属性时,您正在改变它。

export const newMessage = (state, payload) => {
  const { message, sender } = payload;
  return state.map((userMess) => {
    if (userMess.id === message.Id) {
      userMess.messages.push(message); // <-- mutation!!
      userMess.latestMessageText = message.text; // <-- mutation!!
      return userMess;
    } else {
      return userMess;
    }
  });
};

在 React 中更新状态时,您需要浅拷贝状态,并将任何嵌套状态更新为 React 协调工作的新对象引用。

export const newMessage = (state, payload) => {
  const { message, sender } = payload;

  return state.map((userMess) => { // <-- shallow copy of state
    if (userMess.id === message.Id) {
      return { // <-- return new user message object
        ...userMess, // <-- shallow copy of previous user message object
        messages: [message.text, ...userMess.messages], // prepend message, return new array
        latestMessageText: message.text, // update property
      };
    } else {
      return userMess;
    }
  });
};

【讨论】:

  • 这似乎有效,但我将新值添加到数组的开头。我通常使用unshift() 将其添加到开头,但似乎unshift() 现在在其他地方给我带来了问题。
  • @JoshSusa 我明白了,push 将它添加到数组的末尾。我将更新我的答案以将其添加到前面(即前置)。 unshift 将与 push 有相同的问题,改变数组。
猜你喜欢
  • 2019-05-15
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 2020-08-30
  • 2014-08-20
  • 1970-01-01
  • 2018-05-19
相关资源
最近更新 更多