太多的重新渲染。 React 限制渲染次数以防止无限循环。和
Too many re-renders. React limits the number of renders to prevent an infinite loop. and
我正在我的代码中开发一个 mern 应用程序我已经创建了许多组件并使用反应状态钩子和反应上下文 api 钩子来管理通过应用程序的数据流但是当在一个已经存在许多状态的组件中时我创建了一个新状态,它显示错误,我的新状态代码已附加
const [a, seta] = useState("garg");
seta("naman");
我的应用程序在显示许多警告后停止
警告 1:-
at renderWithHooks (react-dom.development.js:14997)
at mountIndeterminateComponent (react-dom.development.js:17811)
at beginWork (react-dom.development.js:19049)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
at invokeGuardedCallback (react-dom.development.js:4056)
at beginWork (react-dom.development.js:23964)
at performUnitOfWork (react-dom.development.js:22776)
at workLoopSync (react-dom.development.js:22707)
at renderRootSync (react-dom.development.js:22670)
at performSyncWorkOnRoot (react-dom.development.js:22293)
at react-dom.development.js:11327
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority (react-dom.development.js:11276)
at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
at flushSyncCallbackQueue (react-dom.development.js:11309)
at flushPassiveEffectsImpl (react-dom.development.js:23620)
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority (react-dom.development.js:11276)
at flushPassiveEffects (react-dom.development.js:23447)
at react-dom.development.js:23324
at workLoop (scheduler.development.js:417)
at flushWork (scheduler.development.js:390)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:157)
警告 2:-
at App (http://localhost:3000/static/js/main.chunk.js:82:81)
我在上面编写状态更新代码的组件代码
import React, { useState, useContext, useEffect } from "react";
import Modal from "react-modal";
import { UserContext } from "./UserContext";
import { AllUserContext } from "./UserContext";
import AlertContext from "./AlertContext";
import Calendar from "react-calendar";
import "../index.css";
import PayModal from "./PayModal";
import { DateContext } from "./UserContext";
import SplitModal from "./SplitModal";
import { ListContext } from "./UserContext";
function Addexpense({ setModal, modal }) {
const [description, setDescription] = useState("");
const [payer, setPayer] = useState("you");
const [cost, setCost] = useState();
const [paymodal, setpaymodal] = useState(false);
const [dtmodal, setdtmodal] = useState(false);
const [splitmodal, setsplitmodal] = useState(false);
// const { listobj, setlistobj } = useContext(ListContext);
const { user, userfriend, usrbalance, setBalance, expense, setExpense } =
useContext(UserContext);
let b = usrbalance;
const [value, onChange] = useState(new Date());
const [a, seta] = useState("json");
seta("naman");
var today = value;
var dd = String(today.getDate()).padStart(2, "0");
var mm = today.toLocaleString("default", { month: "long" });
var yyyy = today.getFullYear();
today = mm + " " + dd + ", " + yyyy;
const [tags, setTag] = useState([]);
const [list, setList] = useState([user.name]);
const [listobj, setlistobj] = useState({ exp: {} });
let _list = { ...listobj };
_list.exp[user.name] = 0;
// setlistobj(_list);
console.log(listobj, "list", _list.exp);
useEffect(() => {
setdtmodal(false);
}, [value]);
const addtag = (e) => {
let filter;
userfriend.map((f) => {
if (f === e.target.value) {
filter = f;
}
});
console.log(filter);
if (filter) {
setTag([...tags, e.target.value]);
setList([...list, e.target.value]);
e.target.value = "";
}
};
const removetag = (i) => {
let a;
setTag(
tags.filter((n, index) => {
a = n;
return index != i;
})
);
setList(
list.filter((_, index) => {
return index != i;
})
);
console.log(a);
};
const m = { color: "red" };
console.log(tags);
const saveexpense = async () => {
if (payer === "you") {
console.log(tags.length);
b = b + (cost / (tags.length + 1)) * tags.length;
} else {
b = b - cost / (tags.length + 1);
}
console.log(b);
const response = await fetch("http://localhost:5000/api/auth/addexpense", {
method: "POST",
headers: {
"Content-Type": "application/json",
"auth-token": localStorage.getItem("token"),
},
body: JSON.stringify({
balance: b,
expenses: tags,
}),
});
const json = await response.json();
setBalance(json.user3.balance);
console.log(json.user3);
};
return (
<div>
<Modal isOpen={modal} className=" expmodalbox ">
<div
style={{
backgroundColor: "#1cc29f",
border: "1px solid #eeeeee",
padding: "5px",
display: "flex",
borderRadius: "10px 10px 0px 0px",
color: "white",
}}
>
<h5 style={{ marginLeft: "150px" }}>Add an Expense</h5>
<button
style={{ position: "absolute", right: "10px" }}
onClick={() => {
setModal(false);
}}
>
<i class="fas fa-times" />
</button>
</div>
<div className=" exp-input p-2">
<label style={{ width: "190px" }} htmlFor="">
With You and:
</label>
<div style={{ position: "relative" }}>
<ul className=" grid grid-cols-3 gap-2 ">
{tags.map((t, i) => {
console.log(t);
return (
<li className="flex align-items-center" key={i}>
<img
src="https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-grey47-50px.png"
alt=""
/>
<span className="mx-1">{t}</span>
<button
style={{ color: "#c0c0c0" }}
onClick={() => {
removetag(i);
}}
>
<i class="fas fa-times" />
</button>
</li>
);
})}
<input
type="text"
placeholder={tags.length ? null : "Enter name"}
onKeyUp={(e) => {
{
return e.key === "Enter" ? addtag(e) : null;
}
}}
style={{ flex: "1" }}
/>
</ul>
</div>
</div>
{tags.length ? (
<div>
<div className="bg-white">
<div className="px-5 pt-4 pb-2 flex exp-main-1">
<img
src="https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/uncategorized/general@2x.png"
alt=""
/>
<div className="ml-3">
<div className="desc">
{" "}
<input
type="text"
name=""
id=""
placeholder="Enter a description"
onChange={(e) => setDescription(e.target.value)}
/>
</div>
<div className="cost mt-2">
{" "}
<span style={{ fontSize: "40px" }}>₹</span>
<input
type="number"
name=""
id=""
placeholder="0.00"
onChange={(e) => setCost(e.target.value)}
/>
</div>
</div>
</div>
<div className="exp-main-2 ml-28 mt-2 ">
<div>
{" "}
Paid by{" "}
<button
onClick={() => {
setpaymodal(true);
}}
>
{payer}
</button>{" "}
and split{" "}
<button
onClick={() => {
setsplitmodal(true);
}}
>
unequally{usrbalance}
</button>
.
</div>
<span className="ml-20">(₹0.00/person)</span>
</div>
<div className="exp-main-3">
<button onClick={() => setdtmodal(true)}>{today}</button>
</div>
</div>
</div>
) : null}
<div className="exp-bottom ">
<div className="exp-bottom-btn">
{" "}
<button className="cancel"> Cancel</button>
<button
className="ml-3 save"
onClick={() => {
saveexpense();
}}
>
Save{" "}
</button>
</div>
</div>
{paymodal ? (
<PayModal setpaymodal={setpaymodal} setPayer={setPayer} />
) : null}
{splitmodal ? (
<SplitModal
setsplitmodal={setsplitmodal}
tags={tags}
list={list}
cost={cost}
/>
) : null}
{dtmodal ? (
<div className="dtmodal">
<div
style={{
backgroundColor: "#1cc29f",
border: "1px solid #eeeeee",
padding: "5px",
display: "flex",
borderRadius: "10px 10px 0px 0px",
color: "white",
}}
>
<h5 style={{ marginLeft: "100px" }}>Choose Date</h5>
<button
style={{ position: "absolute", right: "10px" }}
onClick={() => {
setdtmodal(false);
{
console.log("vh");
}
}}
>
<i class="fas fa-times" />
</button>
</div>
<div className="bg-white px-2 pt-2">
<Calendar onChange={onChange} value={value} className="my" />
</div>
</div>
) : null}
</Modal>
</div>
);
}
export default Addexpense;
我的app.js
import { useState, useEffect } from "react";
import "./index.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Navbar from "./Components/Navbar";
import Home from "./Components/Home";
import Footer from "./Components/Footer";
import Login from "./Components/Login";
import Signup from "./Components/Signup";
import { MyAlert } from "./Components/AlertContext";
import { AuthContext } from "./Components/AuthContext";
import Dashboard from "./Components/Dashboard";
import { UserContext } from "./Components/UserContext";
import { AllUserContext } from "./Components/UserContext";
import { UserFriendContext } from "./Components/UserContext";
import { BalanceContext } from "./Components/UserContext";
import { ExpenseContext } from "./Components/UserContext";
import { DateContext } from "./Components/UserContext";
import Loggedout from "./Components/Loggedout";
import { ListContext } from "./Components/UserContext";
function App() {
const [auth, setAuth] = useState(false);
const [user, setUser] = useState({});
const [allusers, setAll] = useState([]);
const [userfriend, setuserfriend] = useState([]);
const [date, setDate] = useState("naman");
const [usrbalance, setBalance] = useState();
const [expense, setExpense] = useState([]);
const [listobj, setlistobj] = useState({ exp: {} });
const myname = [];
// const [t,sett]=useState(1);
// useEffect(() => {
// const timer=setTimeout(() => {
// sett(t+1)
// }, 1000);
// // Clear timeout if the component is unmounted
// return () => clearTimeout(timer);
// });
const getuser = async (e) => {
const response = await fetch("http://localhost:5000/api/auth/fetchuser", {
method: "GET",
headers: {
"Content-Type": "application/json",
"auth-token": localStorage.getItem("token"),
},
});
const json = await response.json();
console.log(json);
setUser(json);
setuserfriend(json.friends);
setBalance(json.balance);
setExpense(json.expenses);
console.log(userfriend);
};
useEffect(() => {
getuser();
console.log("naman gar");
}, [auth]);
console.log(user.friends, "kutta");
const getallusers = async (e) => {
const response = await fetch(
"http://localhost:5000/api/auth/fetchalluser",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const json = await response.json();
console.log(json);
json.map((u) => {
myname.push(u.name);
console.log(myname);
setAll(myname);
});
};
useEffect(() => {
if (localStorage.getItem("token")) {
setAuth(true);
getallusers();
console.log("auth is true");
} else {
console.log("Auth is false");
}
}, [auth]);
return (
<>
<Router>
<MyAlert>
<ListContext.Provider value={{ listobj, setlistobj }}>
<DateContext.Provider value={{ date, setDate }}>
<AllUserContext.Provider value={{ allusers, setAll }}>
<UserContext.Provider
value={{
user,
setUser,
setuserfriend,
userfriend,
usrbalance,
setBalance,
expense,
setExpense,
}}
>
<AuthContext.Provider value={{ auth, setAuth }}>
<Navbar />
<Switch>
<Route path="/" component={Home} exact></Route>
<Route path="/Login" component={Login} exact></Route>
<Route path="/Signup" component={Signup} exact></Route>
<Route
path="/Dashboard"
component={auth ? Dashboard : Loggedout}
exact
></Route>
</Switch>
</AuthContext.Provider>
</UserContext.Provider>
</AllUserContext.Provider>
</DateContext.Provider>
</ListContext.Provider>
</MyAlert>
</Router>
</>
);
}
export default App;
此代码将导致无限重新渲染循环:
const [a, seta] = useState("garg");
seta("naman");
原因是每个 seta(或任何一般的 setState)在组件内部找到另一个 seta[= 时会重新渲染并执行组件内部的内容20=] 它将再次重新渲染并再次执行代码等等。
为了防止这种情况发生,您必须在 useState('default value') 上提供默认值,或者如果您想在组件挂载时提供一个值,您可以像这样使用 useEffect:
useEffect(() => {
seta("naman")
}, [])
我正在我的代码中开发一个 mern 应用程序我已经创建了许多组件并使用反应状态钩子和反应上下文 api 钩子来管理通过应用程序的数据流但是当在一个已经存在许多状态的组件中时我创建了一个新状态,它显示错误,我的新状态代码已附加
const [a, seta] = useState("garg");
seta("naman");
我的应用程序在显示许多警告后停止 警告 1:-
at renderWithHooks (react-dom.development.js:14997)
at mountIndeterminateComponent (react-dom.development.js:17811)
at beginWork (react-dom.development.js:19049)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
at invokeGuardedCallback (react-dom.development.js:4056)
at beginWork (react-dom.development.js:23964)
at performUnitOfWork (react-dom.development.js:22776)
at workLoopSync (react-dom.development.js:22707)
at renderRootSync (react-dom.development.js:22670)
at performSyncWorkOnRoot (react-dom.development.js:22293)
at react-dom.development.js:11327
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority (react-dom.development.js:11276)
at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
at flushSyncCallbackQueue (react-dom.development.js:11309)
at flushPassiveEffectsImpl (react-dom.development.js:23620)
at unstable_runWithPriority (scheduler.development.js:468)
at runWithPriority (react-dom.development.js:11276)
at flushPassiveEffects (react-dom.development.js:23447)
at react-dom.development.js:23324
at workLoop (scheduler.development.js:417)
at flushWork (scheduler.development.js:390)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:157)
警告 2:-
at App (http://localhost:3000/static/js/main.chunk.js:82:81)
我在上面编写状态更新代码的组件代码
import React, { useState, useContext, useEffect } from "react";
import Modal from "react-modal";
import { UserContext } from "./UserContext";
import { AllUserContext } from "./UserContext";
import AlertContext from "./AlertContext";
import Calendar from "react-calendar";
import "../index.css";
import PayModal from "./PayModal";
import { DateContext } from "./UserContext";
import SplitModal from "./SplitModal";
import { ListContext } from "./UserContext";
function Addexpense({ setModal, modal }) {
const [description, setDescription] = useState("");
const [payer, setPayer] = useState("you");
const [cost, setCost] = useState();
const [paymodal, setpaymodal] = useState(false);
const [dtmodal, setdtmodal] = useState(false);
const [splitmodal, setsplitmodal] = useState(false);
// const { listobj, setlistobj } = useContext(ListContext);
const { user, userfriend, usrbalance, setBalance, expense, setExpense } =
useContext(UserContext);
let b = usrbalance;
const [value, onChange] = useState(new Date());
const [a, seta] = useState("json");
seta("naman");
var today = value;
var dd = String(today.getDate()).padStart(2, "0");
var mm = today.toLocaleString("default", { month: "long" });
var yyyy = today.getFullYear();
today = mm + " " + dd + ", " + yyyy;
const [tags, setTag] = useState([]);
const [list, setList] = useState([user.name]);
const [listobj, setlistobj] = useState({ exp: {} });
let _list = { ...listobj };
_list.exp[user.name] = 0;
// setlistobj(_list);
console.log(listobj, "list", _list.exp);
useEffect(() => {
setdtmodal(false);
}, [value]);
const addtag = (e) => {
let filter;
userfriend.map((f) => {
if (f === e.target.value) {
filter = f;
}
});
console.log(filter);
if (filter) {
setTag([...tags, e.target.value]);
setList([...list, e.target.value]);
e.target.value = "";
}
};
const removetag = (i) => {
let a;
setTag(
tags.filter((n, index) => {
a = n;
return index != i;
})
);
setList(
list.filter((_, index) => {
return index != i;
})
);
console.log(a);
};
const m = { color: "red" };
console.log(tags);
const saveexpense = async () => {
if (payer === "you") {
console.log(tags.length);
b = b + (cost / (tags.length + 1)) * tags.length;
} else {
b = b - cost / (tags.length + 1);
}
console.log(b);
const response = await fetch("http://localhost:5000/api/auth/addexpense", {
method: "POST",
headers: {
"Content-Type": "application/json",
"auth-token": localStorage.getItem("token"),
},
body: JSON.stringify({
balance: b,
expenses: tags,
}),
});
const json = await response.json();
setBalance(json.user3.balance);
console.log(json.user3);
};
return (
<div>
<Modal isOpen={modal} className=" expmodalbox ">
<div
style={{
backgroundColor: "#1cc29f",
border: "1px solid #eeeeee",
padding: "5px",
display: "flex",
borderRadius: "10px 10px 0px 0px",
color: "white",
}}
>
<h5 style={{ marginLeft: "150px" }}>Add an Expense</h5>
<button
style={{ position: "absolute", right: "10px" }}
onClick={() => {
setModal(false);
}}
>
<i class="fas fa-times" />
</button>
</div>
<div className=" exp-input p-2">
<label style={{ width: "190px" }} htmlFor="">
With You and:
</label>
<div style={{ position: "relative" }}>
<ul className=" grid grid-cols-3 gap-2 ">
{tags.map((t, i) => {
console.log(t);
return (
<li className="flex align-items-center" key={i}>
<img
src="https://s3.amazonaws.com/splitwise/uploads/user/default_avatars/avatar-grey47-50px.png"
alt=""
/>
<span className="mx-1">{t}</span>
<button
style={{ color: "#c0c0c0" }}
onClick={() => {
removetag(i);
}}
>
<i class="fas fa-times" />
</button>
</li>
);
})}
<input
type="text"
placeholder={tags.length ? null : "Enter name"}
onKeyUp={(e) => {
{
return e.key === "Enter" ? addtag(e) : null;
}
}}
style={{ flex: "1" }}
/>
</ul>
</div>
</div>
{tags.length ? (
<div>
<div className="bg-white">
<div className="px-5 pt-4 pb-2 flex exp-main-1">
<img
src="https://s3.amazonaws.com/splitwise/uploads/category/icon/square_v2/uncategorized/general@2x.png"
alt=""
/>
<div className="ml-3">
<div className="desc">
{" "}
<input
type="text"
name=""
id=""
placeholder="Enter a description"
onChange={(e) => setDescription(e.target.value)}
/>
</div>
<div className="cost mt-2">
{" "}
<span style={{ fontSize: "40px" }}>₹</span>
<input
type="number"
name=""
id=""
placeholder="0.00"
onChange={(e) => setCost(e.target.value)}
/>
</div>
</div>
</div>
<div className="exp-main-2 ml-28 mt-2 ">
<div>
{" "}
Paid by{" "}
<button
onClick={() => {
setpaymodal(true);
}}
>
{payer}
</button>{" "}
and split{" "}
<button
onClick={() => {
setsplitmodal(true);
}}
>
unequally{usrbalance}
</button>
.
</div>
<span className="ml-20">(₹0.00/person)</span>
</div>
<div className="exp-main-3">
<button onClick={() => setdtmodal(true)}>{today}</button>
</div>
</div>
</div>
) : null}
<div className="exp-bottom ">
<div className="exp-bottom-btn">
{" "}
<button className="cancel"> Cancel</button>
<button
className="ml-3 save"
onClick={() => {
saveexpense();
}}
>
Save{" "}
</button>
</div>
</div>
{paymodal ? (
<PayModal setpaymodal={setpaymodal} setPayer={setPayer} />
) : null}
{splitmodal ? (
<SplitModal
setsplitmodal={setsplitmodal}
tags={tags}
list={list}
cost={cost}
/>
) : null}
{dtmodal ? (
<div className="dtmodal">
<div
style={{
backgroundColor: "#1cc29f",
border: "1px solid #eeeeee",
padding: "5px",
display: "flex",
borderRadius: "10px 10px 0px 0px",
color: "white",
}}
>
<h5 style={{ marginLeft: "100px" }}>Choose Date</h5>
<button
style={{ position: "absolute", right: "10px" }}
onClick={() => {
setdtmodal(false);
{
console.log("vh");
}
}}
>
<i class="fas fa-times" />
</button>
</div>
<div className="bg-white px-2 pt-2">
<Calendar onChange={onChange} value={value} className="my" />
</div>
</div>
) : null}
</Modal>
</div>
);
}
export default Addexpense;
我的app.js
import { useState, useEffect } from "react";
import "./index.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Navbar from "./Components/Navbar";
import Home from "./Components/Home";
import Footer from "./Components/Footer";
import Login from "./Components/Login";
import Signup from "./Components/Signup";
import { MyAlert } from "./Components/AlertContext";
import { AuthContext } from "./Components/AuthContext";
import Dashboard from "./Components/Dashboard";
import { UserContext } from "./Components/UserContext";
import { AllUserContext } from "./Components/UserContext";
import { UserFriendContext } from "./Components/UserContext";
import { BalanceContext } from "./Components/UserContext";
import { ExpenseContext } from "./Components/UserContext";
import { DateContext } from "./Components/UserContext";
import Loggedout from "./Components/Loggedout";
import { ListContext } from "./Components/UserContext";
function App() {
const [auth, setAuth] = useState(false);
const [user, setUser] = useState({});
const [allusers, setAll] = useState([]);
const [userfriend, setuserfriend] = useState([]);
const [date, setDate] = useState("naman");
const [usrbalance, setBalance] = useState();
const [expense, setExpense] = useState([]);
const [listobj, setlistobj] = useState({ exp: {} });
const myname = [];
// const [t,sett]=useState(1);
// useEffect(() => {
// const timer=setTimeout(() => {
// sett(t+1)
// }, 1000);
// // Clear timeout if the component is unmounted
// return () => clearTimeout(timer);
// });
const getuser = async (e) => {
const response = await fetch("http://localhost:5000/api/auth/fetchuser", {
method: "GET",
headers: {
"Content-Type": "application/json",
"auth-token": localStorage.getItem("token"),
},
});
const json = await response.json();
console.log(json);
setUser(json);
setuserfriend(json.friends);
setBalance(json.balance);
setExpense(json.expenses);
console.log(userfriend);
};
useEffect(() => {
getuser();
console.log("naman gar");
}, [auth]);
console.log(user.friends, "kutta");
const getallusers = async (e) => {
const response = await fetch(
"http://localhost:5000/api/auth/fetchalluser",
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);
const json = await response.json();
console.log(json);
json.map((u) => {
myname.push(u.name);
console.log(myname);
setAll(myname);
});
};
useEffect(() => {
if (localStorage.getItem("token")) {
setAuth(true);
getallusers();
console.log("auth is true");
} else {
console.log("Auth is false");
}
}, [auth]);
return (
<>
<Router>
<MyAlert>
<ListContext.Provider value={{ listobj, setlistobj }}>
<DateContext.Provider value={{ date, setDate }}>
<AllUserContext.Provider value={{ allusers, setAll }}>
<UserContext.Provider
value={{
user,
setUser,
setuserfriend,
userfriend,
usrbalance,
setBalance,
expense,
setExpense,
}}
>
<AuthContext.Provider value={{ auth, setAuth }}>
<Navbar />
<Switch>
<Route path="/" component={Home} exact></Route>
<Route path="/Login" component={Login} exact></Route>
<Route path="/Signup" component={Signup} exact></Route>
<Route
path="/Dashboard"
component={auth ? Dashboard : Loggedout}
exact
></Route>
</Switch>
</AuthContext.Provider>
</UserContext.Provider>
</AllUserContext.Provider>
</DateContext.Provider>
</ListContext.Provider>
</MyAlert>
</Router>
</>
);
}
export default App;
此代码将导致无限重新渲染循环:
const [a, seta] = useState("garg");
seta("naman");
原因是每个 seta(或任何一般的 setState)在组件内部找到另一个 seta[= 时会重新渲染并执行组件内部的内容20=] 它将再次重新渲染并再次执行代码等等。
为了防止这种情况发生,您必须在 useState('default value') 上提供默认值,或者如果您想在组件挂载时提供一个值,您可以像这样使用 useEffect:
useEffect(() => {
seta("naman")
}, [])