[英]React setState re-rendering three times
我有这个 useEffect 来存储订单和用户 ID。 我想获取存储在文档中的用户 ID,所以我使用 setID 来存储它。 当我尝试尝试使用该特定 ID 获取用户集合时,会导致错误提示doc(id)
不能为空。 当我尝试console.log(id)
时,它会渲染三次。
第一个渲染- 将为空
第二次渲染- 渲染用户 ID
第三次渲染- 渲染用户 ID
const details = () => {
const classes = useStyles();
const [orders, setOrders] = useState([]);
const [id, setID] = useState("");
// to get the details
useEffect(() => {
const unsubscribe = firestore
.collection("orders")
.doc(Data)
.onSnapshot((snapshot) => {
const arr = [];
arr.push({
id: snapshot.id,
...snapshot.data(),
});
setID(arr[0].userID);
setOrders(arr);
});
return () => {
unsubscribe();
};
}, []);
console.log(id);
return (
<div>
</div>
);
};
我怎样才能解决这个问题? 谢谢你。
如果我理解您的问题,还有另一个 function 您正在使用id
作为参数,并且它在第一次渲染中被调用并且它是空的。
您可以为此效果创建和useEffect
:
useEffect(() => {
if (id !== '') {
foo(id)
}
}, [id]);
如果id
应该始终与orders[0]
保持同步,那么我建议您只有一个 state 变量,而不是两个。 id
可以只是一个计算值:
const [orders, setOrders] = useState([]);
const id = orders[0] ? orders[0].userID : '';
// ...
.onSnapshot((snapshot) => {
const arr = [];
arr.push({
id: snapshot.id,
...snapshot.data(),
});
setOrders(arr);
});
相反,如果在某些情况下id
和orders[0]
应该是不相关的,那么您需要将它们保持在两种状态,但您可能需要批量设置 state。 在许多情况下,react 可以批量调用以自动设置 state,但要做到这一点,代码执行需要在 react 内开始,例如从 useEffect 回调或 onClick 事件开始。
在您的代码中,setStates 发生在onSnapshot
回调中,只要 firebase 决定它应该发生并且 react 不知道它就会发生。 React 无法将这些批处理在一起,因为它不知道发生了什么。 但是你可以告诉 react to batch the changes,如下所示:
import { unstable_batchedUpdates } from "react-dom";
// ...
.onSnapshot((snapshot) => {
const arr = [];
arr.push({
id: snapshot.id,
...snapshot.data(),
});
unstable_batchedUpdates(() => {
setID(arr[0].userID);
setOrders(arr);
});
});
名称的“不稳定”位只是表明他们可能会在下一个主要版本中更改此 api,因此如果您更新您的 react 版本,您需要查看补丁说明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.