[英]Why does my code create a new empty array?
这是我的代码:
const Practice = () => {
const [todo, setTodo] =useState("");
const [todos,setTodos]=useState([])
const onSubmit =async(event) =>{
event.preventDefault();
setTodos((currnet)=>[todo, ...currnet])
setTodo("")
try {
const docRef = await addDoc(collection(db, "todos"), {
todos,
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
}
const onChange = (event)=>{
setTodo(event.target.value)
}
console.log(todos)
return (
<>
<form onSubmit={onSubmit}>
<input onChange={onChange} value={todo} type="text" placeholder="Write" />
<input type="submit" value="GO!!" />
</form>
</>
)
}
我在标签中输入了一些单词,但最后一个输入单词不存在我的 firebase 数据库。 为什么不存在我的数据库? 为什么要创建新的空数组? 在此处输入图像描述
您的问题与钩子的异步性质有关。
在onSubmit
函数中,您正在使用setTodos
钩子(即异步)设置todos
,然后您正在读取todos
值(将其存储到 firebase 中)。
您不能在异步上下文中编写此代码! 事实上,可能是在钩子设置他之前会读取todos
(结果将是并非所有数据都将存储到 firebase 中)。
要解决此错误,您必须以这种方式使用useEffect
钩子:
const Practice = () => {
const [todo, setTodo] =useState("");
const [todos,setTodos]=useState([])
useEffect(() => {
// 1) define an async function in useEffect hook
const storeData = async () => {
try {
const docRef = await addDoc(collection(db, "todos"), {
todos,
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
}
// 2) reset todo
setTodo("");
// 3) store todos into firebase
storeData();
}, [todos]);
const onSubmit =async(event) =>{
event.preventDefault();
setTodos((currnet)=>[todo, ...currnet]);
}
const onChange = (event)=>{
setTodo(event.target.value)
}
return (
<>
<form onSubmit={onSubmit}>
<input onChange={onChange} value={todo} type="text" placeholder="Write" />
<input type="submit" value="GO!!" />
</form>
</>
)
}
解释:
onSubmit
函数只需设置todos
(无需进一步操作);todos
发生变化时,将调用useEffect
钩子(只有此时您才 100% 确定todos
将包含您必须存储到 firebase 中的所有元素!);useEffect
中,您可以清理todo
,然后调用storeData
函数将待办事项存储到todos
中。 附加说明:为什么我在useEffect
中定义了一个异步函数,如果我可以编写如下内容:
useEffect(async () => { // never use async useEffect!!!
try {
const docRef = await addDoc(collection(db, "todos"), {
todos,
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
}, [todos])
你不能写异步useEffect
是有原因的,但我不是专家,所以我强烈建议你阅读这篇文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.