我有一個聊天應用程式。版主點擊“洗掉”后,我需要重新渲染訊息項(部分組件)。因此,我向服務器發送請求以更改所有訊息陣列中的某些訊息,并使用更新的陣列進行回應。接下來,我使用 Reducer 將新陣列設定為 State。正如我在日志中看到的,每次回應后狀態都會更新,但 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 }));
});
為什么當我創建新訊息時它可以作業,但當我嘗試編輯它時卻不行?
uj5u.com熱心網友回復:
只要資料沒問題,很可能問題出在前端。
這段代碼實際上是如何作業的還有很多未知數,但很可能是檢測狀態變化的問題。
當你有你的減速器時:
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's isEqual)。假設之前的狀態是prevState,reducer 之后的狀態是nextState:
prevState[flag] === nextState[flag] // false
prevState.showMessages === nextState.showMessages // true
prevState.showMessages[flag] === nextState.showMessages[flag] // false
最有可能的是,如果你改變你的 reducer 來創建一個新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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497626.html
