现在,我遇到了麻烦,因为我从 Firebase Firestore 收到的数据能够在两条路由上加载,但是,只有在路由链接上单击两次时才会加载,否则旧数据在路由更改之间仍然存在。我的目标是在路线更改时重置数据。
这是我从 Firestore 收到并显示的零件编号网格代码:
var arrSnap:QueryDocumentSnapshot[] = [];
async function populateGrid(){
const currentRoute = useLocation()
var program = currentRoute.replace('/parts-list/', '');
var querySnapshot;
if (program === 'First'){
querySnapshot = await getDocs(collection(db, "Programs", "----", program, "-----", "Parts"));
}else if(program === 'Second'){
querySnapshot = await getDocs(collection(db, "Programs", "----", program, "-----", "Parts"));
}else{
}
const _arrSnap:QueryDocumentSnapshot[] = [];
querySnapshot.forEach((doc) => {
_arrSnap.push(doc);
});
console.log(_arrSnap[0].get("PN"));
arrSnap = [..._arrSnap];
}
export default function CardGrid(){
populateGrid();
return (
<>
<div className="tlCont">
<div className="gridCont">
{[...arrSnap].map((e, i) => {
return (
<div className="gridItm" key={arrSnap[i].get("PN")}>
<Card >
Part Number: {arrSnap[i].get("PN")}
<br></br>
Description: {arrSnap[i].get("DESCRIPTION")}
<br></br>
Form Tool: {arrSnap[i].get("FORM TOOL")}
<br></br>
Trim Tool: {arrSnap[i].get("TRIM TOOL")}
</Card>
</div>
)
})}
</div>
</div>
</>
)
}
我怀疑这与在加载的组件内调用函数“populateGrid()”有关。
populateGrid
被称为无意的副作用populateGrid
改变全局 arrSnap
数组引用。这不会触发 CardGrid
组件重新渲染,因此需要以其他方式触发组件来重新渲染,即第二次单击路线链接。随后的渲染会公开变异的“arrSnap”数组值。populateGrid
应该被称为 ann 有意的副作用,例如使用 useEffect
钩子示例:
export default function CardGrid() {
const { pathname } = useLocation();
const [arrSnap, setArrSnap] = React.useState<QueryDocumentSnapshot[]>([]);
React.useEffect(() => {
const populateGrid = async () => {
const program = /* use pathname to compute program */;
let doc;
switch(program) {
case "First":
doc = collection(db, "Programs", "----", program, "-----", "Parts");
break;
case "Second":
doc = collection(db, "Programs", "----", program, "-----", "Parts");
break;
default:
}
try {
const querySnapshot = await getDocs(doc);
const arrSnap: QueryDocumentSnapshot[] = [];
querySnapshot.forEach((doc) => {
arrSnap.push(doc);
});
setArrSnap(arrSnap);
} catch(error) {
// handle/ignore
}
};
populateGrid();
}, [pathname]);
return (
<div className="tlCont">
<div className="gridCont">
{arrSnap.map((item) => (
<div className="gridItm" key={item.get("PN")}>
<Card>
Part Number: {item.get("PN")}
<br></br>
Description: {item.get("DESCRIPTION")}
<br></br>
Form Tool: {item.get("FORM TOOL")}
<br></br>
Trim Tool: {item.get("TRIM TOOL")}
</Card>
</div>
))}
</div>
</div>
);
}
将逻辑抽象到自定义挂钩中可能是值得的。
基本示例:
const usePopulateGrid = <T extends unknown>() => {
const { pathname } = useLocation();
const [data, setData] = React.useState<T[]>([]);
React.useEffect(() => {
const populateGrid = async () => {
const program = /* use pathname to compute program */;
let doc;
switch(program) {
case "First":
doc = collection(db, "Programs", "----", program, "-----", "Parts");
break;
case "Second":
doc = collection(db, "Programs", "----", program, "-----", "Parts");
break;
default:
}
try {
const querySnapshot = await getDocs(doc);
const data: T[] = [];
querySnapshot.forEach((doc) => {
data.push({
...doc.data(),
id: doc.id
} as T);
});
setData(data);
} catch(error) {
// handle/ignore
}
};
populateGrid();
}, [pathname]);
return data;
};
interface GridData {
id: string;
partNumber: string;
description: string;
formTool: string;
trimTool: string;
}
export default function CardGrid() {
const gridData = usePopulateGrid<GridData>();
return (
<div className="tlCont">
<div className="gridCont">
{gridData.map((item) => (
<div className="gridItm" key={item.id}>
<Card>
Part Number: {item.partNumber}
<br></br>
Description: {item.description}
<br></br>
Form Tool: {item.formTool}
<br></br>
Trim Tool: {item.trimTool}
</Card>
</div>
))}
</div>
</div>
);
}