通常,我在尝试卸载组件时会尝试保存全局状态更新,因为react-apollo
使我很难进行不必要的重新提取。
我正在将所有已删除的注释ID添加到deletedCommentsQueue
,并且当Comments
组件卸载时,我想更新我的全局状态,但是当要卸载的deletedCommentsQueue
组件更改为空数组,即使我们在尝试进行更新之前可以看到所有评论ID。
我为你们做了一个简单的SandBox。
这是我给有兴趣的人的代码
import React, { useState, useEffect, useContext, createContext } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
const UserContext = createContext();
const comments = [
{ _id: 1, body: "first" },
{ _id: 2, body: "second" },
{ _id: 3, body: "third" }
];
const Comments = ({ commentIds }) => {
const [deletedCommentsQueue, setDeletedCommentsQueue] = useState([]);
const addToQueue = commentId => {
setDeletedCommentsQueue([...deletedCommentsQueue, commentId]);
};
const { loggedUser, setLoggedUser } = useContext(UserContext);
useEffect(
() => () => {
console.log("cleaning");
console.log("deletedCommentsQueue", deletedCommentsQueue);
const updatedComments = loggedUser.comments.filter(
commentId => !deletedCommentsQueue.includes(commentId)
);
console.log(updatedComments);
setLoggedUser({
...loggedUser,
comments: updatedComments,
likes: {
...loggedUser.likes,
comments: loggedUser.likes.comments.filter(
commentId => !deletedCommentsQueue.includes(commentId)
)
}
});
},
[]
);
return (
<div>
{deletedCommentsQueue.length > 0 && (
<h1>Comment ids for deletion {deletedCommentsQueue.join(" ")}</h1>
)}
{commentIds.map(commentId => (
<Comment
deleted={deletedCommentsQueue.includes(commentId)}
key={commentId}
comment={comments.find(c => c._id === commentId)}
deleteCommentFromCache={() => addToQueue(commentId)}
/>
))}
</div>
);
};
const Comment = ({ comment, deleted, deleteCommentFromCache }) => (
<div>
{deleted && <h2>Deleted</h2>}
<p>{comment.body}</p>
<button disabled={deleted} onClick={deleteCommentFromCache}>
Delete
</button>
</div>
);
const App = () => {
const [loggedUser, setLoggedUser] = useState({
username: "asafaviv",
comments: [1, 2, 3],
likes: {
comments: [1, 2]
}
});
const [mounted, setMounted] = useState(true);
return (
<div className="App">
<UserContext.Provider value={{ loggedUser, setLoggedUser }}>
{mounted && <Comments commentIds={loggedUser.comments} />}
</UserContext.Provider>
<br />
<button onClick={() => setMounted(!mounted)}>
{mounted ? "Unmount" : "Mount"}
</button>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
答案 0 :(得分:0)
我猜这是因为您声明的效果具有空依赖性([]
)。这样,在安装组件时,效果将运行一次。
因此,我想在其关闭的上下文中,deletedCommentQueues
的值等于首次安装该组件的时间=> []
。
我尝试了您的codeandbox,如果您删除了[]
(这意味着每次更新都会调用该效果),则在卸载组件时会获得正确的值,但是...每次更新都会调用该函数不能解决您的缓存问题。
恕我直言,我建议您在父组件中设置状态(const [deletedCommentsQueue, setDeletedCommentsQueue] = useState([]);
,并在mounted
值变为false
而不是的时候将数据保存到所需的任何位置从组件内部观看。