useOptimistic
是 React19 提供了一个新的 hooks,他可以实现乐观更新,使得数据更新效果更加友好。
乐观更新:在进行服务器请求接口时,先在用户界面上预先处理成功的结果(假设操作成功),然后再发送请求到服务器进行确认。如果服务器返回错误,前端再进行相应的回滚或错误处理。
useOptimistic 的语法
const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
useOptimistic
接收两个参数:
state
:初始状态updateFn
:一个函数,接收当前状态和乐观更新值,返回新一个和当前状态和新值合并的新状态。
useOptimistic
返回值:
optimisticState
:是updateFn
返回的新状态optimisticState
。addOptimistic
:addOptimistic
是需要乐观更新时要调用的函数。它接受一个状态,会传递给updateFn
的第二个参数,返回新状态optimisticValue
。
上述的描述可能有点抽象,我们进行场景模拟来解释下该 hook 的使用。
举个例子
我们直接举一个实际应用的例子来看,现在要实现一个评论列表,每次新增评论时,会立刻把结果显示在列表中,并同步到服务器,但是,如果服务器返回错误,则进行回滚提示。我们先来创建一个 App 组件。
App组件
export default function App() {
const [comments, setComments] = useState([{ text: "第一条评论", sending: false }]);
async function addComment(formData) {
const newComment = await postComment(formData.get("comment"));
setComments((comments) => [...comments, { text: newComment }]);
}
return <CommentSection comments={comments} addComment={addComment} />;
}
CommentSection组件
我们要实现一个评论组件,包含列表展示功能和评论表单提交功能。
function CommentSection({ comments, addComment }) {
const formRef = useRef();
const [optimisticComments, addOptimisticComment] = useOptimistic(comments, (state, newComment) => [
...state,
{
text: newComment,
sending: true,
failed: false,
},
]);
async function handleFormSubmit(formData) {
const newComment = formData.get("comment");
addOptimisticComment(newComment); // 乐观更新
formRef.current.reset();
try {
await addComment(formData);
} catch (error) {
handleFailure(newComment);
}
}
function handleFailure(failedComment) {
// 提示失败
}
return (
<>
<div>
{optimisticComments.map((comment, index) => (
<div key={index} style={{ color: comment.failed ? "red" : "black" }}>
{comment.text}
{!!comment.sending && <small> (发送中...)</small>}
</div>
))}
</div>
<form action={handleFormSubmit} ref={formRef}>
<input type="text" name="comment" placeholder="评论..." />
<button type="submit">提交</button>
</form>
</>
);
}