为什么我的代码创建一个新的空数组?



这是我的代码:

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将在hook设置他之前被读取(结果将是不是所有的数据将被存储到firebase)。

要解决这个bug,你必须这样使用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>
</>
)
}

解释:

  1. onSubmit功能只需要设置todos(无需进一步操作);
  2. todos改变时,useEffect钩子将被调用(只有在这个时候你才100%确定todos将包含所有你必须存储到firebase中的元素!);
  3. 现在在useEffect中,你可以清理todo,然后调用storeData函数将todos存储到firebase。

附加说明:为什么我在useEffect中定义了一个async函数,如果我可以这样写:

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是有原因的,但我不是专家,所以我强烈建议你阅读这篇文章。

相关内容

  • 没有找到相关文章

最新更新