我有一个ReactJS网站,但我还是一个初学者。
我有两个组件:
- 第一个是根路径
/
的页面,在用户访问该路由时必须从Web服务器渲染,我使用了useEffect实现这一点。 - 第二个是
/mostraMaterie/:id
,也必须在另一个请求到Web服务器后进行渲染。
第一个组件工作得很好,而第二个组件不会触发useEffect函数。
当用户在/
组件上单击按钮时,会被重定向到具有相应ID的/mostraMateria/:id
。
问题出现在/mostraMateria
组件中,我有另一个useEffect函数,但它没有被触发。
如评论所建议的,以下是JSFiddle中的mostraMateria文件:mostraMaterie.js
App.js处理用户连接。
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import MostraMaterie from "./Contenuti/MostraMaterie";
import "./App.css";
import Main from "./Contenuti/Main";
function App() {
return (
<Router>
<Switch>
<Route path="/mostraMateria/:id" component={MostraMaterie} />{" "}
<Route exact path="/" component={Main} />{" "}
</Switch>{" "}
</Router>
);
}
export default App;
Main.js 负责处理页面渲染,如果位置是/
,则运行完美。
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import Indirizzi from "./Indirizzi";
import Bottone from "../Util/Bottone";
import "../App.css";
import FullNavBar from "../NavBar/FullNavBar";
function Main() {
const [indirizzi, cambiaIndirizzi] = useState([]);
const fetchIndirizzi = () => {
async function prendiIndirizzi() {
let indirizzi = await fetch(
"https://vps.lellovitiello.tk/Riassunty/API/indirizzi.php"
);
let ind = await indirizzi.json();
for (let i = 0; i < ind.length; i++) {
async function prendiMaterie() {
let materie = await fetch(
`https://vps.lellovitiello.tk/Riassunty/API/materie.php?indirizzo=${ind[i].Indirizzo}`
);
materie = await materie.json();
for (let materia of materie) {
Object.defineProperty(
materia,
"nome",
Object.getOwnPropertyDescriptor(materia, "Materia")
);
delete materia["Materia"];
Object.defineProperty(
materia,
"id",
Object.getOwnPropertyDescriptor(materia, "IDMateria")
);
delete materia["IDMateria"];
delete materia["Indirizzo"];
}
Object.defineProperty(
ind[i],
"nome",
Object.getOwnPropertyDescriptor(ind[i], "Indirizzo")
);
delete ind[i]["Indirizzo"];
Object.assign(ind[i], { dati: materie });
Object.assign(ind[i], { id: i });
}
await prendiMaterie();
}
console.log("Main.js", ind);
cambiaIndirizzi(ind);
}
prendiIndirizzi();
};
useEffect(fetchIndirizzi, []);
return (
<React.Fragment>
<FullNavBar elementi={indirizzi} />{" "}
<Link to="/Login">
<Bottone TestoBottone="Per caricare un riassunto" />
</Link>{" "}
{indirizzi.map(indirizzo => {
console.log(indirizzo);
return <Indirizzi dati={indirizzo} />;
})}
</React.Fragment>
);
}
export default Main;
MostraMaterie.js 处理页面渲染,如果位置是 /mostraMaterie/:id
,但不起作用。
import React, { useEffect, useState } from "react";
import "../App.css";
import history from "../Util/history";
import { Link } from "react-router-dom";
import FullNavBar from "../NavBar/FullNavBar";
import Indirizzi from "./Indirizzi";
import Bottone from "../Util/Bottone";
function MostraMaterie(props) {
const [anni, cambiaAnni] = useState([]);
// *** this function is never called ***
const fetchAnni = () => {
async function prendiAnni() {
let anniJson = await fetch(
"https://vps.lellovitiello.tk/Riassunty/API/ottieniAnni.php"
);
let idMateria = props.match.params.id;
let ann = [];
anniJson = await anniJson.json();
for (let anno of anniJson) {
async function prendiAnteprime() {
let anteprimeFetch = await fetch(
`https://vps.lellovitiello.tk/Riassunty/API/anteprima.php?idMateria=${idMateria}&anno=${anno}`
);
anteprimeFetch = await anteprimeFetch.json();
for (let anteprima of anteprimeFetch) {
Object.defineProperty(
anteprima,
"nome",
Object.getOwnPropertyDescriptor(anteprima, "Titolo")
);
Object.defineProperty(
anteprima,
"id",
Object.getOwnPropertyDescriptor(anteprima, "ID")
);
delete anteprima["Titolo"];
delete anteprima["ID"];
}
let annoOggetto = {
nome: anno + "",
anteprime: anteprimeFetch
};
ann.push(annoOggetto);
}
await prendiAnteprime();
}
debugger;
cambiaAnni(ann);
}
console.log("Vengo eseguito");
prendiAnni();
};
useEffect(fetchAnni, []);
console.log(history.location);
return (
<React.Fragment>
<FullNavBar indirizzi={anni} />{" "}
<Link to="/Login">
<Bottone TestoBottone="Per caricare un riassunto" />
</Link>{" "}
<h1> CIao CIAO CIAO CIAOC </h1>{" "}
{
//*** this depends on the response of the web server ***
anni.map(anno => {
console.log("Ciao");
return <Indirizzi dati={anno} />;
})}{" "}
</React.Fragment>
);
}
export default MostraMaterie;
我该如何让这个工作起来?
编辑
我已经移除了<FullNavBar indirizzi={anni} />{" "}
,现在我的请求已发送到服务器并且触发了“fetchAnni”函数。
问题是,我需要被移除的那段代码,似乎<FullNavBar indirizzi={anni} />{" "}
在调用fetchAnni
之前就被渲染了,即使像Artur建议的添加await prendiAnni
和async fetchAnni
也不起作用。
我还改变了从useEffect(fetchAnni,[]);
到useEffect(fetchAnni, [props.location.pathname]);
,它是一个字符串。
history.location
是一个对象,useEffect 的第二个参数应该只与原始变量数组(如字符串、数字等)一起使用,因此您应该选择在 useEffect 中使用的原始字段(例如props.match.params.id
)。 - Arthur