我有一个聊天应用程序。我需要在主持人点击"删除"后重新呈现消息项(部分组件)。因此,我向服务器发送请求,以更改所有消息数组中的某些消息,并使用更新的数组进行响应。接下来,我将新的数组使用减速机状态。正如我在日志中看到的,每次响应后状态都会更新,但是React不呈现消息项Component。
此外,当我创建新消息时,相同的代码也可以工作(下面的示例)。屏幕上的更改仅在以下顺序之后出现:发送新消息-单击"删除";-再发一条新消息。
请求服务器删除"点击:
axios
.patch(`${serverName}/messages/${patchTarget}/${messageId}`)
.then((response) => {
let fetchedMessages = [...response.data];
dispatch(setMessages({ fetchedMessages, flag }));
});
减速器:
setMessages(state, action) {
const flag = action.payload.flag;
// state.showMessages is responsible for showed messages
state[flag] = [...action.payload.fetchedMessages];
state.showMessages[flag] = [...state[flag]];
}
服务器:
let MESSAGES = {
DISPUTE: [{}],
SPEC: [{}]
};
app.get("/messages/:target", (req, res) => {
const fetchTarget = req.params.target;
res.status(200).json(MESSAGES[fetchTarget as keyof typeof MESSAGES]);
});
app.post("/messages/:target", (req, res) => {
const newMessage = req.body;
const pushTarget = req.params.target;
MESSAGES[pushTarget as keyof typeof MESSAGES].push(newMessage);
res.status(200).json(MESSAGES[pushTarget as keyof typeof MESSAGES]);
});
app.patch("/messages/:target/:id", (req, res) => {
const patchTarget = req.params.target;
const messageId = Number(req.params.id);
const element = MESSAGES[patchTarget as keyof typeof MESSAGES][messageId];
if (!element.deletedText) element.deletedText = element.text;
if (!element.deleted) element.deleted = !element.deleted;
element.text = "Message has been deleted by moderator";
res.status(200).json(MESSAGES[patchTarget as keyof typeof MESSAGES]);
});
在另一个组件中创建一个新消息并发送它的工作代码:
axios
.post(`${serverName}/messages/${pushTarget}`, newMessageFunc())
.then((response) => {
let fetchedMessages = [...response.data];
dispatch(setMessages({ fetchedMessages, flag }));
});
为什么当我创建新消息时它工作,但当我试图编辑它时它不工作?
只要数据是正确的,最有可能的问题是在前端。
这段代码是如何工作的还有很多未知之处,但最有可能的是检测状态变化的问题。
当你有你的减速器:
setMessages(state, action) {
const flag = action.payload.flag;
// state.showMessages is responsible for showed messages
state[flag] = [...action.payload.fetchedMessages];
state.showMessages[flag] = [...state[flag]];
}
数组具有新的标识,但showMessages
对象仍然相同-这可能导致未检测到更改。React将尝试通过身份检查(===
)来查找更改,而不是通过深度相等检查(即lodash
的isEqual
)。假设前一状态为prevState
,减速后状态为nextState
:
prevState[flag] === nextState[flag] // false
prevState.showMessages === nextState.showMessages // true
prevState.showMessages[flag] === nextState.showMessages[flag] // false
最有可能的是,如果你改变你的减速器来创建一个新的showMessages
对象,它会工作得很好:
setMessages(state, action) {
const flag = action.payload.flag;
// state.showMessages is responsible for showed messages
state[flag] = [...action.payload.fetchedMessages];
state.showMessages = {
...state.showMessages,
[flag]: [...state[flag]],
};
}
之后,所有的对象将被检测为不同于之前的状态:
prevState[flag] === nextState[flag] // false
prevState.showMessages === nextState.showMessages // false
prevState.showMessages[flag] === nextState.showMessages[flag] // false