为啥在组件加载时不调用 useEffect(()=...,[]) ?
Posted
技术标签:
【中文标题】为啥在组件加载时不调用 useEffect(()=...,[]) ?【英文标题】:Why is useEffect(()=...,[]) not being called on component load?为什么在组件加载时不调用 useEffect(()=...,[]) ? 【发布时间】:2022-01-07 05:29:42 【问题描述】:有许多与 useEffect() 和在初始页面渲染时运行有关的问题。即使在确保我的代码在传递给 useEffect 的参数方面是正确的之后,我也遇到了同样的问题。
useEffect(() =>
const token = Cookies.get('token');
setRole(Cookies.get('role'));
fetch(`$process.env.API_URL/user/user-details`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"user_id": role,
"language": "en",
"api_token": token
)
)
.then((user) => user.json())
.then((thisUserData) =>
if (thisUserData.status_code == 200)
setThisUser(thisUserData)
)
, [])
由于某种原因,组件安装后似乎没有调用它。
这是完整的页面代码:
import Header from "../../../components/header"
import useRouter from "next/router"
import Link from 'next/link'
import Pagination from "../../../components/datatable/pagination"
import Cookies from "js-cookie"
import parseCookies from "nookies"
import useState, useEffect from "react"
import Modal, Button from "react-bootstrap";
import UserSidebar from "../../../components/user_sidebar"
import TabButtonUser from "../../../components/tabbuttonuser"
import Address from "../../../components/address"
const AdminUsers = ( data ) =>
const router = useRouter()
// const limit = 3
// const lastPage = Math.ceil(totalPage / limit)
// console.log(data)
// console.log(listUsers)
/**
* Manage states
*/
const [show, setShow] = useState(false);
const [isEdit, setIsEdit] = useState(false);
const [fullNname, setFullName] = useState("");
const [emailID, setEmailID] = useState("");
const [country_code, setCountry_code] = useState("");
const [phone_number, setPhone_number] = useState("");
const [company_access, setCompany_access] = useState("");
const [isActive, setActive] = useState("");
const [userID, setUserId] = useState("");
const [role, setRole] = useState("");
const [thisUserData, setThisUser] = useState()
useEffect(() =>
const token = Cookies.get('token');
setRole(Cookies.get('role'));
fetch(`$process.env.API_URL/user/user-details`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"user_id": role,
"language": "en",
"api_token": token
)
)
.then((user) => user.json())
.then((thisUserData) =>
if (thisUserData.status_code == 200)
setThisUser(thisUserData)
)
, [])
/**
* Clear values
*/
const handleClose = () =>
setShow(false)
setIsEdit(false);
setUserId("")
setFullName("");
setEmailID("");
setCountry_code("");
setPhone_number("");
;
const handleShow = () => setShow(true);
/**
* Add User
* @param * e
* @returns
*/
const addUser = async (e) =>
e.preventDefault();
const token = Cookies.get('token');
if (!token)
return
redirect:
destination: '/',
permanent: false,
,
const resUser = await fetch(`$process.env.API_URL/user/create-sub-admin`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"full_name": fullNname,
"email_id": emailID,
"country_code": "+1",
"phone_number": phone_number,
"api_token": token
)
)
const res2User = await resUser.json();
console.log(res2User);
if (res2User.status_code == 200)
handleClose();
setFullName("");
setEmailID("");
setCountry_code("");
setPhone_number("");
/**
* Get user details basis of user id for edit purpose
* @param * id
* @returns
*/
const getUser = async (id) =>
// e.preventDefault();
setIsEdit(true);
setShow(true);
setUserId(id)
const token = Cookies.get('token');
if (!token)
return
redirect:
destination: '/',
permanent: false,
,
const userData = await fetch(`$process.env.API_URL/user/user-details`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"user_id": id,
"language": "en",
"api_token": token
)
)
const userData2 = await userData.json();
console.log(userData2);
if (userData2.status_code == 200)
// handleClose();
setFullName(userData2?.data?.full_name);
setEmailID(userData2?.data?.email_id);
setCountry_code(userData2?.data?.phone_number?.country_code);
setPhone_number(userData2?.data?.phone_number?.phone_number);
/**
* Remove user
* Api is pending
* @param * id
*/
const removeUser = async (id) =>
/**
*Update User
*
* @return *
*/
const updateUser = async () =>
// e.preventDefault();
const token = Cookies.get('token');
if (!token)
return
redirect:
destination: '/',
permanent: false,
,
const resUser = await fetch(`$process.env.API_URL/user/update-user`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"user_id": userID,
"full_name": fullNname,
"email_id": emailID,
"country_code": "+1",
"phone_number": phone_number,
"api_token": token,
"is_active": isActive
)
)
const res2User = await resUser.json();
console.log(res2User);
if (res2User.status_code == 200)
setFullName("");
setEmailID("");
setCountry_code("");
setPhone_number("");
setIsEdit(false);
setShow(false);
setUserId("")
const address =
"address_line": "",
"city_name": "",
"state_name": "",
"zip_code": ""
return (
<>
<Header />
<div className="container">
<div className="row">
<div className="col-3">
<UserSidebar data=thisUserData />
</div>
<div className="col">
<div className="sidebarwrap">
/* <TabButtonUser id=data?._id /> */
<h3 className="acc_title">My Company</h3>
<h2 className="login_name">Alliance Credit</h2>
<div className="acc_email">
<a href="mailto:email@company.com">email@company.com</a>
</div>
<div className="acc_phone">+1234567890</div>
<Address address=address />
<div className="ac_left acc_title">All Team Members</div>
<div className="ac_right">
role.indexOf('admin') > -1 ?
<button className="btn btnedit" onClick=handleShow>Add Sub-Admin</button>
: ''
</div>
<div className="clearfix"></div>
<div className="listing">
<table id="example" className="table table-striped">
<thead>
<tr>
<th><div>Sr. Number</div></th>
<th><div>User Name</div></th>
<th><div>Date Added</div></th>
<th><div>Email</div></th>
<th><div>Actions</div></th>
</tr>
</thead>
<tbody>
data?.map((item, index) => (
<tr key=index>
<td>index + 1</td>
<td>item.full_name</td>
<td>item.date_added</td>
<td>item.email_id</td>
<td>
<>
<button className="btn viewmore" onClick=() => getUser(item._id)>Edit User</button>
</>
</td>
</tr>
))
</tbody>
</table>
/* <Pagination page=page totalPage=totalPage lastPage=lastPage /> */
</div>
</div>
</div>
</div>
</div>
<Modal show=show onHide=handleClose>
<Modal.Header closeButton>
<Modal.Title>isEdit == false
? "Add Sub-Admin"
: "Edit Sub-Admin"
</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="popupform">
<form method="POST">
<div className="row">
<div className="col">
<label htmlFor="fullname" className="form-label">Full Name</label>
<input className="form-control" name="fullname" type="text" id="fullname" value=fullNname onChange=(e) => setFullName(e.target.value) />
</div>
</div>
<div className="row">
<div className="col">
<label htmlFor="emailID" className="form-label">Email</label>
<input className="form-control" name="emailID" type="text" id="emailID" value=emailID onChange=(e) => setEmailID(e.target.value) />
</div>
</div>
<div className="row">
<div className="col">
<label htmlFor="phone_number" className="form-label">Phone Number</label>
<input className="form-control" name="phone_number" type="text" id="phone_number" value=phone_number onChange=(e) => setPhone_number(e.target.value) />
</div>
</div>
<div className="row">
<div className="col">
isEdit ? (
<>
<label htmlFor="phone_number" className="form-label">Active status</label>
<select className="form-control form-select" onChange=(e) => setActive(e.target.value)>
<option value="0">Active</option>
<option value="1">Deactivate</option>
</select>
</>
) : ''
</div>
</div>
<div>
<input className="form-control" name="userID" type="hidden" id="company_logo_en" value=userID />
</div>
</form>
</div>
</Modal.Body>
<Modal.Footer>
isEdit == false
? <>
<Button variant="secondary" className="btn btnedit" onClick=handleClose>Cancel</Button>
<Button variant="primary" onClick=addUser>Add User</Button>
</>
:
<>
<Button variant="primary" className="btn btnremove" onClick=removeUser>Remove User</Button>
<Button variant="primary" className="btn btnedit">Reset User</Button>
<Button variant="primary" onClick=updateUser>Save</Button>
</>
</Modal.Footer>
</Modal>
</>
)
/**
*
*
* @export
* @param * query: page = 1, data = null, totalPage = 10
* @return *
*/
// export async function getServerSideProps( query: page = 1, data = null, totalPage = 10 )
export async function getServerSideProps(ctx)
// const start = +page === 1 ? 0 : (+page + 1)
// const locale, locales, defaultLocale, asPath = useRouter();
const token = parseCookies(ctx)
if (!token)
return
redirect:
destination: '/',
permanent: false,
,
const res = await fetch(`$process.env.API_URL/user/list-sub-admin`,
method: "POST",
headers:
"Content-Type": "application/json",
,
body: JSON.stringify(
"language": 'en',
"api_token": token,
)
)
const data = await res.json()
/**
* limit, start, search item
*/
return
props:
data: data?.data || [],
export default AdminUsers
我确信这是我错过的一些简单的事情(通常是这样),但我似乎无法发现它。
谢谢。
【问题讨论】:
“这是完整的页面代码” 这并不是真的那么有用。我们只看到AdminUsers
组件。这还不足以用于运行您的代码。如果你为你的项目创建了一个在线沙箱会更好。例如,试试codesandbox.io。
它真的没有被调用,还是由于role
仍然具有其初始值,您是否从获取请求中得到了非 200 响应?设置状态是一个异步操作:***.com/questions/38558200/….
它似乎没有被调用,因为我的断点都没有命中函数中的任何地方。但是@Max给出的答案解决了这个问题。似乎对 state 的调用导致页面在 useEffect() 完成之前重新呈现,使其看起来好像根本没有被调用。去掉 useState() 调用就完美解决了。
【参考方案1】:
我不清楚这个问题,但我试着写下我所看到的:你已经定义了 useEddect 和没有 deps 的 fetch。在该提取中,您使用角色状态,该状态在第一次初始化为空字符串。您在同一个 useEffect 中使用 setRole 设置角色,但由于前面的原因,这没有效果。
我的建议是删除角色状态并重新定义 useEffect 如下:
useEffect(() =>
const token = Cookies.get('token');
const role = Cookies.get('role');
fetch(`$process.env.API_URL/user/user-details`,
method: 'POST',
headers:
'Content-Type': 'application/json',
,
body: JSON.stringify(
user_id: role,
language: 'en',
api_token: token,
),
)
.then((user) => user.json())
.then((thisUserData) =>
if (thisUserData.status_code == 200)
setThisUser(thisUserData);
);
, []);
【讨论】:
以上是关于为啥在组件加载时不调用 useEffect(()=...,[]) ?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 useState 钩子在 useEffect() 中使用循环时不更新
useEffect 中的套接字连接事件在创建组件时不起作用,但在 React 中刷新页面后起作用