React在单击NavLink时渲染组件,但在刷新时崩溃



我有一个组件Dashboard.js,它将在单击NavLink时渲染,但在刷新页面时会崩溃。我不知道该怎么办。

错误显示cannot read properties of undefinded (Budget)

在NavLink点击时,页面将不会使用";goals图表数据"当我刷新时,整个东西都崩溃了。如果我导航到"/home",然后单击Dashboard.js,预算数据确实会填充图表/页面加载,但如果我刷新,它仍然会崩溃。

import React from "react";
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
LineChart,
Line,
} from "recharts";
const Dashboard = ({ user, budget, personBudget }) => {
// data for Goals Chart
// data for Goals Chart
// data for Goals Chart
const goalsChartData = [
{
name: "Week 1",
Goal: user.budget ? user.budget.weekOneGoals : null,
},
{
name: "Week 2",
Goal: user.budget ? user.budget.weekTwoGoals : null,
},
{
name: "Week 3",
Goal: user.budget ? user.budget.weekThreeGoals : null,
},
{
name: "Week 4",
Goal: user.budget ? user.budget.weekFourGoals : null,
},
{
name: "Week 5",
Goal: user.budget ? user.budget.weekFiveGoals : null,
},
{
name: "Week 6",
Goal: user.budget ? user.budget.weekSixGoals : null,
},
];
// data for Friends Chart
// data for Friends Chart
// data for Friends Chart
const friendsChartData = [
{
name: "Week 1",
Person1: personBudget[0] ? personBudget[0].weekOneGoals : null,
Person2: personBudget[1] ? personBudget[1].weekOneGoals : null,
Person3: personBudget[2] ? personBudget[2].weekOneGoals : null,
},
{
name: "Week 2",
Person1: personBudget[0] ? personBudget[0].weekTwoGoals : null,
Person2: personBudget[1] ? personBudget[1].weekTwoGoals : null,
Person3: personBudget[2] ? personBudget[2].weekTwoGoals : null,
},
{
name: "Week 3",
Person1: personBudget[0] ? personBudget[0].weekThreeGoals : null,
Person2: personBudget[1] ? personBudget[1].weekThreeGoals : null,
Person3: personBudget[2] ? personBudget[2].weekThreeGoals : null,
},
{
name: "Week 4",
Person1: personBudget[0] ? personBudget[0].weekFourGoals : null,
Person2: personBudget[1] ? personBudget[1].weekFourGoals : null,
Person3: personBudget[2] ? personBudget[2].weekFourGoals : null,
},
{
name: "Week 5",
Person1: personBudget[0] ? personBudget[0].weekFiveGoals : null,
Person2: personBudget[1] ? personBudget[1].weekFiveGoals : null,
Person3: personBudget[2] ? personBudget[2].weekFiveGoals : null,
},
{
name: "Week 6",
Person1: personBudget[0] ? personBudget[0].weekSixGoals : null,
Person2: personBudget[1] ? personBudget[1].weekSixGoals : null,
Person3: personBudget[2] ? personBudget[2].weekSixGoals : null,
},
];
return (
<div
style={{
background: "grey",
display: "grid",
justifyContent: "center",
}}
>
<h4 style={{ textAlign: "center" }}>Your Goals</h4>
<BarChart
width={500}
height={300}
data={goalsChartData}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5,
}}
barSize={30}
>
<XAxis dataKey="name" scale="point" padding={{ left: 10, right: 10 }} />
<YAxis />
<Tooltip />
<Legend />
<CartesianGrid strokeDasharray="3 3" />
<Bar dataKey="Goal" fill="#8884d8" />
</BarChart>
<LineChart
width={500}
height={300}
data={friendsChartData}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Legend />
<Line
type="monotone"
dataKey="Person2"
stroke="#8884d8"
strokeDasharray="5 5"
/>
<Line
type="monotone"
dataKey="Person1"
stroke="#82ca9d"
strokeDasharray="3 4 5 2"
/>{" "}
<Line
type="monotone"
dataKey="Person3"
stroke="#e21c7f"
strokeDasharray="3 4 5 2"
/>
</LineChart>
</div>
);
};
export default Dashboard;

App.js

import "./App.css";
import { Routes, Route } from "react-router-dom";
import { useEffect, useState } from "react";
import Login from "./pages/Login";
import Signup from "./pages/Signup";
import { Paper } from "@material-ui/core";
import Navbar from "./components/Navbar";
import Home from "./components/Home";
import Profile from "./components/Profile";
import RequireAuth from "./pages/RequireAuth";
import useStyles from "./pages/useStyles";
import Budget from "./components/Goals";
import ProfileDelete from "./pages/ProfileDelete";
import People from "./components/People";
import Friends from "./components/Friends";
import Person from "./components/Person";
import Dashboard from "./components/Dashboard";
import Goals from "./components/Goals";
function App() {
const [user, setUser] = useState(null);
const [isAuthenticated, setIsAuthenticated] = useState(false);
const classes = useStyles();
const [people, setPeople] = useState([]);
const [userFriends, setUserFriends] = useState([]);
const [budget, setBudget] = useState([]);
const [personBudget, setPersonBudget] = useState([]);
useEffect(() => {
fetch("/authorize_user").then((res) => {
if (res.ok) {
res.json().then((user) => {
setIsAuthenticated(true);
setUser(user);
});
}
});
fetch("/people").then((res) => {
if (res.ok) {
res.json().then(setPeople);
}
});
fetch("/friends").then((res) => {
if (res.ok) {
res.json().then(setUserFriends);
}
});
fetch("/budgets").then((res) => {
if (res.ok) {
res.json().then(setBudget);
}
});
fetch("/person_budgets").then((res) => {
if (res.ok) {
res.json().then(setPersonBudget);
}
});
}, []);
// useEffect(() => {
// }, [])
return (
<>
<Paper className={classes.pageContent} elevation={24}>
<Navbar
user={user}
setUser={setUser}
isAuthenticated={isAuthenticated}
setIsAuthenticated={setIsAuthenticated}
/>
</Paper>
<Routes>
<Route
path="login"
element={
<Login
user={user}
setUser={setUser}
isAuthenticated={isAuthenticated}
setIsAuthenticated={setIsAuthenticated}
/>
}
/>
<Route
path="signup"
element={
<Signup
user={user}
setUser={setUser}
isAuthenticated={isAuthenticated}
setIsAuthenticated={setIsAuthenticated}
/>
}
/>
<Route path="/" element={<Home />} />
<Route
path="home"
element={
<Paper className={classes.pageContent}>
<Home />{" "}
</Paper>
}
/>
<Route
path="profile"
element={
// <RequireAuth isAuthenticated={isAuthenticated}>
<Paper className={classes.pageContent}>
<Profile
user={user}
setUser={setUser}
isAuthenticated={isAuthenticated}
setIsAuthenticated={setIsAuthenticated}
/>
</Paper>
//{" "}
// </RequireAuth>s
}
/>
<Route
path="goals"
element={
<Paper className={classes.pageContent}>
<Goals user={user} budget={budget} />
</Paper>
}
/>
<Route
path="profile/delete"
element={
<ProfileDelete
user={user}
setUser={setUser}
setIsAuthenticated={setIsAuthenticated}
/>
}
/>
<Route
path="people"
element={
<People
people={people}
user={user}
setUser={setUser}
setIsAuthenticated={setIsAuthenticated}
userFriends={userFriends}
/>
}
/>
<Route
path="/friends"
element={
<Friends user={user} userFriends={userFriends} people={people} />
}
/>
<Route
path="/people/:id"
element={
<Paper className={classes.pageContent}>
<Person
user={user}
people={people}
userFriends={userFriends}
setUserFriends={setUserFriends}
/>
</Paper>
}
/>
<Route
path="dashboard"
element={
<Dashboard
user={user}
budget={budget}
personBudget={personBudget}
/>
}
/>
{/* <Route path="goals" element={<Goals user={user} />} /> */}
</Routes>
</>
);
}
export default App;

问题是因为您的API请求尚未完成加载,这就是您获得未定义的原因。对于这种情况,您需要包括一个加载状态,这样类似的东西才能工作。

App.js

function App() {
... all of your code above render
const loaded = people && userFriends && budget && personBudget;
if (!loaded){
return '...loading'
}

return (
...what you already have in your render
)
}

尽管我鼓励您重构代码,因为在一个文件中有这么多api调用和setStates会导致大量的重新呈现。我鼓励您查看useContext挂钩,并为每个api调用创建一个提供程序,而不是将它们全部包含在应用程序中。

最新更新