我寫了一個組件叫做Chat
(為簡單起見省略了一些部分):
function Chat() {
const containerRef = React.useRef(null);
const messages = useQuery({
queryKey: ["messages"],
queryFn: api.getMessages
});
const createMessage = useMutation({
mutationFn: (message) => api.createMessage(message),
onMutate: (message) => {
// 1. cancels query, updates cache, returns previous value
optimisitcUpdate(messages, message);
// 2. scroll to bottom
const { current: container } = containerRef;
// ? won't work, because the DOM is not updated yet
container?.scrollTo(0, container.scrollHeight);
// ?? works, because the DOM is updated, but it's hacky
setTimeout(() => container?.scrollTo(0, container.scrollHeight))
},
});
return (
<div id="messages" ref={containerRef}>
{messages.data?.map((message) => (
<div key={message.uuid}>{message.body}</div>
))}
</div>
);
}
這很簡單。useQuery
獲取所有訊息,useMutation
創建新訊息并回傳所有訊息。
每當createMessage
發生時,我都希望樂觀地更新訊息,然后滾動到底部(就像任何其他聊天行為一樣)。
問題是,我無法在flushSync
inside做useMutation
,所以作為一種解決方法,我將邏輯包裝在 asetTimeout
中,但這是一種 hacky 方式。
我想知道是否有比這更強大的方法。
uj5u.com熱心網友回復:
你可以依賴DOM 渲染后useEffect
執行:
useEffect(() => {
const { current: container } = containerRef;
container?.scrollTo(0, container.scrollHeight);
)/*, [you may want to put some dependencies here to limit rendering]*/};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/524577.html
下一篇:如何在樣式化組件上進行條件渲染?