You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Todo应用中多评论输入框内容同步显示的问题?

解决Todo评论输入框内容同步的问题

你遇到的问题本质是所有评论输入框共享了同一个状态变量,导致输入时所有框内容同步。下面提供两种可行方案:

方案一:用对象存储每个Todo的输入状态

将原来的单个inputComment状态改成对象,以Todo的id为键,存储对应输入框的内容。这样每个输入框绑定自己独立的状态字段。

修改步骤:

  1. 更新状态定义:
// 替换原来的const [inputComment, setInputComment] = useState('');
const [inputComments, setInputComments] = useState({});
  1. 修改评论输入框的value和onChange:
<TextField
    id="standard-basic"
    placeholder="Enter comment:"
    variant="standard"
    value={inputComments[todo.id] || ''} // 取当前todo对应的输入值,默认空字符串
    onChange={event => setInputComments(prev => ({
        ...prev,
        [todo.id]: event.target.value // 更新对应todo的输入内容
    }))}
/>
  1. 更新AddComment函数,提交后清空对应Todo的输入框:
const AddComment = async (id, newComment) => {
    const todoDoc = doc(db, "todos", id);
    if (newComment == "") {
        setOpen(true);
    } else {
        await updateDoc(todoDoc, {
            "comments": arrayUnion(newComment)
        });
        // 提交后清空当前todo的输入框
        setInputComments(prev => ({
            ...prev,
            [id]: ''
        }));
        // 去掉刷新,改用重新获取数据更新列表,体验更流畅
        const q = query(todosRef, orderBy("timestamp", "desc"));
        const data = await getDocs(q);
        setNewTodos(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    }
}

方案二:拆分独立的评论输入组件

把评论输入部分拆成单独的组件,每个组件内部维护自己的输入状态,天然隔离不同Todo的输入内容,代码结构更清晰。

步骤:

  1. 创建CommentInput组件:
const CommentInput = ({ todoId, onAddComment }) => {
    const [inputComment, setInputComment] = useState('');

    const handleSubmit = async () => {
        if (inputComment.trim() === '') {
            return;
        }
        await onAddComment(todoId, inputComment);
        setInputComment(''); // 提交后清空输入
    };

    return (
        <Box sx={{ marginTop: "10px", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
            <TextField
                id="standard-basic"
                placeholder="Enter comment:"
                variant="standard"
                value={inputComment}
                onChange={event => setInputComment(event.target.value)}
            />
            <AddCommentIcon 
                className="icon" 
                sx={{ alignSelf: "flex-end", fontSize: "1.3rem" }} 
                onClick={handleSubmit} 
            />
        </Box>
    );
};
  1. 在原组件中替换原来的评论输入部分:
// 替换原来的<Box>...</Box>
<CommentInput 
    todoId={todo.id} 
    onAddComment={AddComment} 
/>
  1. 调整AddComment函数(优化刷新逻辑):
const AddComment = async (id, newComment) => {
    const todoDoc = doc(db, "todos", id);
    if (newComment == "") {
        setOpen(true);
    } else {
        await updateDoc(todoDoc, {
            "comments": arrayUnion(newComment)
        });
        // 重新获取数据更新列表
        const q = query(todosRef, orderBy("timestamp", "desc"));
        const data = await getDocs(q);
        setNewTodos(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
    }
}

两种方案都能解决你的问题,方案二更符合React组件化的设计思想,推荐使用。

内容的提问来源于stack exchange,提问作者Luka Miljković

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 04:54:12