使用 useEffect 无限循环
我正在创建一个在 firebase 中更新数据的项目,但是我已经控制台记录了数据并且它不断地通过。
如何从本质上停止循环以免崩溃。
import "./App.css";
import "semantic-ui-css/semantic.min.css";
import { Container, Divider, Card } from "semantic-ui-react";
import Header from "./components/Header";
import Cards from "./components/Cards/index";
import { useState, useEffect } from "react";
import { AppProvider } from "./Context/Context.js";
import "firebase/compat/auth";
import {} from "firebase/firestore";
import * as FirestoreService from "./components/service/firebase";
import firebase from "@firebase/app-compat";
function App() {
const [user, setUser] = useState(null);
const [cloudFucntions, setCloudFucntions] = useState();
const [error, setError] = useState();
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
setUser(user);
const unsubscribe = FirestoreService.getCloudFunctionItems(
(querySnapshot) => {
const updatedCloundFunctions = querySnapshot.docs.map((docSnapshot) =>
docSnapshot.data()
);
setCloudFucntions(updatedCloundFunctions);
console.log(updatedCloundFunctions);
},
(error) => setError("list-item-get-fail")
);
return unsubscribe;
});
}, [cloudFucntions]);
return (
<AppProvider>
<div>
<Container>
<Header />
<Divider horizontal section>
Cloud Function Monitor
</Divider>
{user ? (
<Card.Group itemsPerRow="4">
{cloudFucntions &&
cloudFucntions.map((cloudFunction) => {
return (
<Cards
key={cloudFunction.id}
cloudFunction={cloudFunction}
></Cards>
);
})}
</Card.Group>
) : (
<h2> Please sign in using the button in the top right. </h2>
)}
</Container>
</div>
</AppProvider>
);
}
export default App;
我尝试使用空数组并且不传递任何内容,但出现错误: 警告:列表中的每个子项都应该有一个唯一的“key”道具。 警告:失败的 prop 类型:提供给 CardContent
的 prop children
无效,需要 ReactNode。 警告:函数作为 React 子项无效。如果您返回一个组件而不是从渲染中返回,则可能会发生这种情况。或者也许您打算调用此函数而不是返回它。
I am creating a project that updates my data in firebase, however I have console logged the data and its constantly coming through.
How do I stop the loop essentially so that it doesn't crash.
import "./App.css";
import "semantic-ui-css/semantic.min.css";
import { Container, Divider, Card } from "semantic-ui-react";
import Header from "./components/Header";
import Cards from "./components/Cards/index";
import { useState, useEffect } from "react";
import { AppProvider } from "./Context/Context.js";
import "firebase/compat/auth";
import {} from "firebase/firestore";
import * as FirestoreService from "./components/service/firebase";
import firebase from "@firebase/app-compat";
function App() {
const [user, setUser] = useState(null);
const [cloudFucntions, setCloudFucntions] = useState();
const [error, setError] = useState();
useEffect(() => {
firebase.auth().onAuthStateChanged((user) => {
setUser(user);
const unsubscribe = FirestoreService.getCloudFunctionItems(
(querySnapshot) => {
const updatedCloundFunctions = querySnapshot.docs.map((docSnapshot) =>
docSnapshot.data()
);
setCloudFucntions(updatedCloundFunctions);
console.log(updatedCloundFunctions);
},
(error) => setError("list-item-get-fail")
);
return unsubscribe;
});
}, [cloudFucntions]);
return (
<AppProvider>
<div>
<Container>
<Header />
<Divider horizontal section>
Cloud Function Monitor
</Divider>
{user ? (
<Card.Group itemsPerRow="4">
{cloudFucntions &&
cloudFucntions.map((cloudFunction) => {
return (
<Cards
key={cloudFunction.id}
cloudFunction={cloudFunction}
></Cards>
);
})}
</Card.Group>
) : (
<h2> Please sign in using the button in the top right. </h2>
)}
</Container>
</div>
</AppProvider>
);
}
export default App;
I have tried using an empty array and not passing anything through however i get the errors:
Warning: Each child in a list should have a unique "key" prop.
Warning: Failed prop type: Invalid prop children
supplied to CardContent
, expected a ReactNode.
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,您不能对效果最终更新的效果使用依赖项,这就是导致渲染循环的原因。对于
useEffect
挂钩,回调中根本没有引用cloudFucntions
,因此它不是依赖项。对于 Firebase 连接,更常见的是使用挂载useEffect
挂钩,即空依赖项数组。我还看到该组件不会取消订阅
onAuthStateChanged
检查。由于第二个云函数的获取似乎并不依赖于用户
,因此您应该将它们分为自己的效果和订阅清理。这仅意味着
key={cloudFunction.id}
不是一个足够唯一的 id,无法用作 React 键。 React 键必须在同级中是唯一的。 除非别无选择,否则不要使用数组索引作为键。不建议这样做。如果您的云函数对象有重复的 id,或者返回重复的云函数,您应该在后端修复此问题。如果这不是您可以在后端解决的问题,那么当您在前端收到它们时,您需要生成唯一的 ID。
例子:
对于其中的每一个,我们都需要查看我怀疑的
Cards
组件。这些警告似乎与CartContent
组件有关。您可以添加Cards
组件和其他相关代码,以及任何 propTypes 定义,我们可以进一步完善答案,或者您可以在 SO 上发布一个新问题,因为这些对于以下问题来说是相当课外的渲染循环和 React 键。You can't generally use a dependency for an effect that the effect ultimately updates, this is what leads to render looping. For the
useEffect
hook,cloudFucntions
isn't referenced at all in the callback, so it's not a dependnecy. With firebase connections it's more common to use a mountinguseEffect
hook, i.e. an empty dependency array.I see also that the component doesn't unsubscribe from the
onAuthStateChanged
check. Since the the second cloud functions fetching doesn't appear to be dependent on theuser
, you should split these into their own effects and subscription clean ups.This only means that
key={cloudFunction.id}
isn't a unique enough id to be used as a React key. React keys must be unique among siblings. Don't use the array index as key unless you've no other choice. It's not recommended.If your cloud function objects have duplicate ids, or there are duplicate cloud functions being returned you should fix this in the backend. If this isn't something you can resolve in the backend then you'll need to generate unique ids when you receive them in the frontend.
Example:
For each of these we'd need to see the
Cards
component I suspect. The warnings are with regard to aCartContent
component it seems. You can add theCards
component and other relevant code, along with any propTypes definitions and we can further refine answer, or you can post a new question on SO since these are rather extra-curricular to the issue of the render looping and React keys.您对 useEffect 的依赖不正确。对
setCloudFucntions
的调用将重新触发 useEffect(因为它设置了cloudFucntions
),您不需要它,您的效果不使用
cloudFucntions
。警告与渲染中的键有关,看来 cloudFunction.id 可能不是唯一的。
你可以这样做
You have an incorrect dependency on the useEffect. The call to
setCloudFucntions
will retrigger useEffect (because it setscloudFucntions
)You don't need it, your effect does not use
cloudFucntions
.The warning is concerning the key in the render, it seems that cloudFunction.id may not be unique.
You could do this