为什么我在 React JS 中的代码会进入满足这两个条件的无限循环?



import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom";
import firebase from '../../config/firebaseConfig'
import SingleEventSummary from './SingleEventSummary'
import { getEvent } from "./../../store/actions/eventActions";
import "./SingleEvent.css";
const SingleEvent = props => {
	const id = props.match.params.id;
	const [eventItem, seteventItem] = useState([]);
	const [isFavourite, setIsFavourite] = useState("no");
	//getting specific event
	useEffect(() => {
		const db = firebase.firestore().collection('newEvents').doc(id)
		db.onSnapshot(snapshot => {
			seteventItem(snapshot.data())
		})
	}, [id])
	//checking if there is favourite
	useEffect(() => {
		const db = firebase.firestore().collection('users').doc(props.auth.uid)
	  
		db.get().then(snapshot => {
		  const data = snapshot.data()
		  const faves = data && snapshot.data().favorites || []
	  
		  faves.includes(id) ? setIsFavourite("yes") : setIsFavourite("no")
		},(error) => console.error(error))
	  },[isFavourite])

	//setting as favourites
	const favouriteClick = (uid, eid) => {
		debugger;
		let initFav = firebase.firestore().collection('users').doc(uid);
		initFav.get().then(snapshot => {
			const arrayUnion = firebase.firestore.FieldValue.arrayUnion(eid);
			initFav.update({
				favorites: arrayUnion,
			});
			setIsFavourite("yes")
		},(error) => console.error(error))
	}
	//remove favourites
	const removeFavourite = () => {
		debugger;
		const initFavo = firebase.firestore().collection('users').doc(props.auth.uid);
		initFavo.get().then(snapshot => {
			if (snapshot.data().favorites) {
				if (snapshot.data().favorites.includes(id)) {
					let data = snapshot.data().favorites.filter(el => el != id )
					initFavo.update({
						favorites: data,
					});
					setIsFavourite("no")
				}
			}
		},(error) => console.error(error))
		return () => initFavo()
	}
	console.log("wtf is this shit", isFavourite)

	if (isFavourite == "no") {
		return (
			<main className="single-event_main">
				<a className="waves-effect waves-light btn" onClick={favouriteClick(props.auth.uid, id)}>Add As Favourites!!</a>
			</main>
		);
}
	 else {
		return (
			<main className="single-event_main">
				<div className="row">
					<div className="col s6">
						<a className="waves-effect waves-light btn" disabled>Favourite Event!!</a>
					</div>
					<div className="col s6">
						<a className="waves-effect waves-light btn" onClick={removeFavourite}>Remove From Favourites!!</a>
					</div>
				</div>
			</main>
		);
	} 
};
export default SingleEvent;

我正在尝试在钩子中设置值,比较用户数据库中是否存在事件 id(如果他/她已将该事件设置为收藏夹(。

....
const [isFavourite, setIsFavourite] = useState("no");
//checking if there is favourite
useEffect(() => {
debugger;
const db = firebase.firestore().collection('users').doc(props.auth.uid)
db.onSnapshot(snapshot => {
debugger;
if(snapshot.data()) {
if (snapshot.data().favorites) {
if (snapshot.data().favorites.includes(id)) {
setIsFavourite("yes")
}
else if(!snapshot.data().favorites.includes(id)){
setIsFavourite("no")
}
}
}
}, (error) => console.error(error));
return () => db()
},[])
....

问题是,反应在两个条件内无休止地设置钩子值是和否。一直被困在这个小时。

任何形式的帮助将不胜感激!!

jus 提供了一点重构 ->这只是更容易阅读

useEffect(() => {
const db = firebase.firestore().collection('users').doc(props.auth.uid)
db.onSnapshot(snapshot => {
const data = snapshot.data()
const faves = data && snapshot.data().favorites || []
faves.includes(id) ? setIsFavourite("yes") : setIsFavourite("no")
},(error) => console.error(error))
return () => db()
},[])

我不明白为什么你的代码会循环,也许我们需要更多代码,如上面的评论者所提到的。

好的,现在您已经向我们展示了更多代码。我可以非常自信地说,这是因为您正在调用收藏夹单击"添加为收藏夹"按钮的onClick。

这导致了一个奇怪的循环。 改变

onClick={favouriteClick(props.auth.uid, id)

onClick={() => favouriteClick(props.auth.uid, id)

不客气!

你应该对这个钩子有一个停止条件,useEffect每次渲染某些东西时都会触发钩子,所以你最终会更改 prop 和渲染,然后触发useEffect更改 props 并触发生命周期 Hookrender

你应该有这样的东西

useEffect(() => {
// call database
},[setFavorite]) // here goes stop condition for useEffect

如果setFavorite仍然false它不会再次触发触发器,或者如果setFavorite为假并且来自数据库的请求将其设置为true那么下次如果您再次触发useEffect并且setFavorite仍然trueuseEffect不会执行。

有关更多详细信息,请阅读官方文档 https://reactjs.org/docs/hooks-effect.html

如果您要在setIsFavourite()中更新 Firebase,那么您正在创建一个更改,该更改将由.onSnapshot侦听器接收。这将强制无限循环:条件触发器更改>侦听条件>条件触发器无穷无尽>更改。

在这种情况下,您需要从.onSnapshot切换到一次性.get侦听器,或者需要添加一个条件来防止更改传播。此自定义条件将特定于您的实现,除非您展示使用更多代码并帮助我们了解您要实现的目标(不过这应该是一个单独的问题(,否则我们无法真正提供帮助。所以我怀疑在这种情况下是前者。

相关内容

  • 没有找到相关文章

最新更新