如何在reactjs中避免不必要的Firestore读取?
免责声明:我希望我的描述一针见血,因为我在这个问题上花了很多时间。请在评论中给我反馈,以改进我的问题,这样你就有足够的信息给我一个好的答案。我创建这个应用程序是为了支持科罗纳疫苗中心作为一个慈善项目,但我没有得到报酬,我尽量避免为firestore阅读花费金钱。因此,我想减少它们如何在reactjs中避免不必要的Firestore读取?,reactjs,firebase,google-cloud-firestore,Reactjs,Firebase,Google Cloud Firestore,免责声明:我希望我的描述一针见血,因为我在这个问题上花了很多时间。请在评论中给我反馈,以改进我的问题,这样你就有足够的信息给我一个好的答案。我创建这个应用程序是为了支持科罗纳疫苗中心作为一个慈善项目,但我没有得到报酬,我尽量避免为firestore阅读花费金钱。因此,我想减少它们 我有两个用ReactJS构建的web应用程序: 用户可以生成登记单 管理员可以将用户签入 1。应用程序只有firestore写入。每个用户一次写入。我将不涉及该应用程序的更多细节,因为它不会有问题 二,。当每个用户签
我有两个用ReactJS构建的web应用程序:
CheckInView
、UserArchive
和UserView
。该应用程序使用Firestore数据库和一个用户集合。我构建应用程序只是为了正常工作,现在我想修改代码以避免对firestore应用程序进行不必要的读取
对于CheckInView
我需要.onSnapshot()
,这样管理员就不需要手动刷新页面并自动查看新用户。它只读取未签入的用户(。其中(“checkedin”,“==”,null)
)
UserArchive
应显示已签入的所有用户(。其中(“checkedin”,“!=”,null)
)。它有一个用于筛选/搜索特定用户的输入字段。每天大约有200-300个用户,最多有10个用户没有同时登记。这意味着每天有200-300名新用户。因此,每天有200-300多人阅读
对于UserView
我正在再次阅读,但只有一个用户。我真的不知道为什么我的应用程序这么难扩展读取。当您从UserView
返回UserArchive
时,可能会发生这种情况,因为它一次又一次地获取所有用户
我可以在UserArchive
中从.onSnapshot()
切换到.get()
,但我不确定这个问题是否解决了。也许不是
也许有人比我更有firestore读取方面的经验,可以检查我的代码,并看到这么多读取的问题
这是我的mutch精简代码,具有基本功能:
import { useEffect, useState } from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import firebase from "./firebase";
function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/checkin" component={CheckInView} />
<Route exact path="/userview/:udi" component={UserView} />
<Route exact path="/userarchive" component={UserArchive} />
</Switch>
</Router>
</div>
);
}
export default App;
export const CheckInView = () => {
const [users, setUsers] = useState([]);
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("users")
.where("infected", "==", null)
.onSnapshot((fetchedUsers) => {
setUsers(fetchedUsers.docs.map((user) => user.data()));
});
return () => {
unsubscribe();
};
}, [setUsers]);
return (
<div>
<Link to="/userarchive">- Archive</Link>
{users.map((user) => (
<div key={user.uid}>
<Link to={`/userview/${user.uid}`}>{user.name}</Link>
</div>
))}
</div>
);
};
const UserArchive = () => {
const [users, setUsers] = useState([]);
const [search, setSearch] = useState("");
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("users")
.where("infected", "!=", null)
.onSnapshot((fetchedUsers) => {
setUsers(fetchedUsers.docs.map((user) => user.data()));
});
return () => {
unsubscribe();
};
}, [setUsers]);
return (
<div>
<Link to="/checkin">- CheckIn</Link>
<input
type="text"
value={search}
placeholder="Search..."
onChange={(e) => setSearch(e.target.value)}
/>
{users
.filter((e) => e.name.toLowerCase().includes(search.toLowerCase()))
.map((user) => (
<div key={user.uid}>
<Link to={`/userview/${user.uid}`}>{user.name}</Link>
</div>
))}
</div>
);
};
const UserView = ({ match }) => {
const [user, setUser] = useState();
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("users")
.doc(match.params.uid)
.onSnapshot((user) => {
setUser(user.data());
});
return () => {
unsubscribe();
};
}, [setUser, match.params.uid]);
return (
<>
<div>{user !== undefined ? user.name : "No Valid User."}</div>
<Link to="/checkin">Back</Link>
</>
);
};
从“react”导入{useffect,useState};
从“react Router dom”导入{BrowserRouter as Router,Switch,Route,Link};
从“/firebase”导入firebase;
函数App(){
返回(
);
}
导出默认应用程序;
导出常量CheckInView=()=>{
const[users,setUsers]=useState([]);
useffect(()=>{
const unsubscribe=firebase
.firestore()
.收集(“用户”)
。其中(“已感染”,“==”,null)
.onSnapshot((fetchedUsers)=>{
setUsers(fetchedUsers.docs.map((user)=>user.data());
});
return()=>{
取消订阅();
};
},[setUsers]);
返回(
-档案馆
{users.map((用户)=>(
{user.name}
))}
);
};
constuserarchive=()=>{
const[users,setUsers]=useState([]);
const[search,setSearch]=useState(“”);
useffect(()=>{
const unsubscribe=firebase
.firestore()
.收集(“用户”)
。其中(“已感染”,“!=”,空)
.onSnapshot((fetchedUsers)=>{
setUsers(fetchedUsers.docs.map((user)=>user.data());
});
return()=>{
取消订阅();
};
},[setUsers]);
返回(
-签到
setSearch(e.target.value)}
/>
{用户
.filter((e)=>e.name.toLowerCase().includes(search.toLowerCase()))
.map((用户)=>(
{user.name}
))}
);
};
const UserView=({match})=>{
const[user,setUser]=useState();
useffect(()=>{
const unsubscribe=firebase
.firestore()
.收集(“用户”)
.doc(匹配.params.uid)
.onSnapshot((用户)=>{
setUser(user.data());
});
return()=>{
取消订阅();
};
},[setUser,match.params.uid]);
返回(
{user!==未定义?user.name:“无有效用户。”}
返回
);
};
将一个.onSnapshot()
添加到App
组件中,并将其传递给所有视图,并根据我的要求对其进行过滤,这是一个好主意吗
users.fiter(e=>e.checkedin==true)
用于用户存档
users.fiter(e=>e.checkedin==false)
用于checkenView
users.fiter(e=>e.uid==march.params.uid)
用于用户视图
您好,读取的原因是,每次组件渲染时,都会运行效果
函数
例如
const UserView = ({ match }) => {
const [user, setUser] = useState();
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("users")
.doc(match.params.uid)
.onSnapshot((user) => {
setUser(user.data());
});
return () => {
unsubscribe();
};
});
return (
<>
<div>{user !== undefined ? user.name : "No Valid User."}</div>
<Link to="/checkin">Back</Link>
</>
);
};
通过以上更改,仅当安装的组件useffect
钩子还依赖于match.params.uid
时,效果才会运行,因此最好在依赖项数组中传递它[match.params.uid]
很抱歉,这是我的问题。在我的real app中,所有useEffects都取决于相关的setUsers
和match.params.uid
。我更新了我的代码。如果是这样,我认为您应该登录effect函数来检测完整的端到端流调用了多少次。通过这样做,您将检测并部分调用服务most
useEffect(() => {
const unsubscribe = firebase
.firestore()
.collection("users")
.doc(match.params.uid)
.onSnapshot((user) => {
setUser(user.data());
});
return () => {
unsubscribe();
};
}, []);