试图在React组件中呈现Firestore信息-使用useRef()而不是重新呈现和useState()会引发错误



我目前正在使用以下React组件:

function Dashboard(props) {
const loadingDash = useRef(true);
const dataDash = useRef([]);
// var [loading, setLoading] = useState(true)
// var [data, setData] = useState([])
// Style info goes here - unimportant to question at hand
var userName,
userEmail,
planRank,
designRank,
implementRank,
testRank,
maintRank;
useEffect(() => {
db.collection('Users')
.doc(props.user)
.onSnapshot({ includeMetadataChanges: true }, function (userInfo) {
dataDash.current = userInfo.data();
console.log('dataDash: ', dataDash);
if (dataDash.current !== undefined) {
loadingDash.current = false;
console.log('Loading dash: ', loadingDash);
}
});
});
if (loadingDash) {
return <h1>We're watching, and we're waiting</h1>; // Activation spinner here
}
return (
<div className={classes.app}>
<NavBar loggedIn={props.isLoggedIn} />
<div className={classes.page}>
<img className={classes.photo} src={defaultprofile} alt={'UserPhoto'} />
<h1 className={classes.profilename}>UserName</h1>
<h4 className={classes.profileinfo}>Email: email</h4>
<h4 className={classes.profileinfo}>Rank: "Rank"</h4>
</div>
<div className={classes.page}>
<h1 className={classes.progressname}>Learning Progress</h1>
<p className={classes.progressinfotop}>Planning - 75%</p>
<LinearProgress
variant="determinate"
className={classes.progressbar}
value={75}
/>
<p className={classes.progressinfo}>Design - 50%</p>
<LinearProgress
variant="determinate"
className={classes.progressbar}
value={50}
/>
<p className={classes.progressinfo}>Implementation - 100%</p>
<LinearProgress
variant="determinate"
className={classes.progressbar}
value={100}
/>
<p className={classes.progressinfo}>Testing & Deployment - 75%</p>
<LinearProgress
variant="determinate"
className={classes.progressbar}
value={75}
/>
<p className={classes.progressinfo}>Maintenance - 25%</p>
<LinearProgress
variant="determinate"
className={classes.progressbarbottom}
value={25}
/>
</div>
<div className={classes.page}>
<p className={classes.continuetext}>
Want to continue where you left off, click below to continue!
</p>
<button className={classes.buttons}>
<Link to="/LearnMore" className={classes.buttonlinks}>
Continue
</Link>
</button>
</div>
<div className={classes.footer}>
Copyright: Allison Broski, Shelby McKay, Maurice Fuentes, Timothy
Carpenter, Tanner Porteous
<p>Oakland University</p>
</div>
</div>
);
}
export default Dashboard;

我的基本问题是,我试图从Firestore数据库中检索信息,然后在页面上显示各个属性。然而,我遇到了异步获取数据的问题。为了解决这个问题,我引用了这个和一个建议使用React状态的例子。这就是我的组件的基础。然而,当我在React中使用useState()功能时,它引发了以下错误:

每次渲染后,React Hook useEffect内部对"loading"变量的赋值将丢失。若要随时间保留该值,请将其存储在useRef Hook中,并将可变值保留在".current"属性中。否则,您可以直接在useEffect中移动此变量。

为了解决错误,我将其更改为使用useRef()功能。但是,现在loading更改时组件不会重新渲染,因为根据文档,这不是useRef()的特性。我看过的其他所有教程都说要使用useState(),但我显然做不到。

有没有关于解决这些问题的方法的建议,这样我就可以准确地呈现Firestore数据库中的数据?

loading变量应处于状态(useState(。我认为显示错误消息是因为useEffect调用中没有依赖项,所以基本上每次更改都会在每次道具更改时重新呈现整个组件,实际上,它会覆盖render值。

我相信您只想在组件首次呈现时运行侦听器一次。在这种情况下,您应该传递一个空数组作为第二个参数(依赖项(

useEffect(() => {
db.collection('Users').doc(props.user).onSnapshot({
includeMetadataChanges: true
},
function(userInfo) {
dataDash.current = userInfo.data()
console.log('dataDash: ', dataDash)
if (dataDash.current !== undefined) {
setLoading(false);
}
})
}, []); // <-- here

最新更新