只调用一次回调函数
call callback function only once
我正在做一个前面有 ReactJS 的全栈项目,它有用户管理。
有些页面只有在用户连接时才可用,所以基本上,我通过询问我的服务器来检查它,我在我的 NavBar.js
组件中进行检查(因为它在每个页面中使用)。
看起来像这样:
const Navigation = ({ callback }) => {
useEffect(() => {
axios({
method: "GET",
withCredentials: true,
url: process.env.REACT_APP_SERVER + "/user",
}).then((res) => {
if (callback)
callback(res.data.username);
setUser(res.data.username);
}).catch((e) => {
if (callback)
callback(null);
});
}, [callback])
return (
<div>Some navbar stuff</div>
)
}
export default Navigation;
在我的其他页面中,我使用这样的导航组件:
const PublishContent = () => {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
const handleUserName = e => {
setUser(e);
setLoading(false);
}
return (
<div>
<Navigation callback={handleUserName} />
{
!loading && <div>{user ? <div>CONNECTED</div> : <div> NOT CONNECTED</div>} </div>
}
</div>
)
}
export default PublishContent;
我的问题是我的handleUserName
被调用了3次,我不明白为什么,即使callback
是我的UseEffect
的依赖列表,它应该是常数...
此外,由于useState
是异步的,即使用户登录了,第一次我的user
也是未定义的。
你知道我怎么解决这个问题吗?另外,你能告诉我我正在做的事情吗(检查用户是否已通过身份验证,对你来说听起来很奇怪?谢谢。
每次调用 handleUserName
时,它都会调用 setUser 和 setLoading,它们都会启动重新渲染。当 PublishContent 组件重新呈现(在本例中为两次)时,它将创建一个新函数并将其分配给 handleUserName,然后将其传递到您的 Navigation 组件和您的 useEffect,导致您的 useEffect 重新 运行 自依赖性已更改(重新渲染后的新功能)。要解决您的问题,您只需要像这样
将 handleUserName 包装在 useCallback 中
const handleUserName = useCallback((e) => {
setUser(e)
setLoading(false)
}, [])
您也不应该在导航中调用 setUser。如果你需要访问它,你可以将它作为 prop
const PublishContent = () => {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
const handleUserName = useCallback(e => {
setUser(e);
setLoading(false);
}, [])
return (
<div>
<Navigation callback={handleUserName} user={user} />
{
!loading && <div>{user ? <div>CONNECTED</div> : <div> NOT CONNECTED</div>} </div>
}
</div>
)
}
export default PublishContent;
我正在做一个前面有 ReactJS 的全栈项目,它有用户管理。
有些页面只有在用户连接时才可用,所以基本上,我通过询问我的服务器来检查它,我在我的 NavBar.js
组件中进行检查(因为它在每个页面中使用)。
看起来像这样:
const Navigation = ({ callback }) => {
useEffect(() => {
axios({
method: "GET",
withCredentials: true,
url: process.env.REACT_APP_SERVER + "/user",
}).then((res) => {
if (callback)
callback(res.data.username);
setUser(res.data.username);
}).catch((e) => {
if (callback)
callback(null);
});
}, [callback])
return (
<div>Some navbar stuff</div>
)
}
export default Navigation;
在我的其他页面中,我使用这样的导航组件:
const PublishContent = () => {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
const handleUserName = e => {
setUser(e);
setLoading(false);
}
return (
<div>
<Navigation callback={handleUserName} />
{
!loading && <div>{user ? <div>CONNECTED</div> : <div> NOT CONNECTED</div>} </div>
}
</div>
)
}
export default PublishContent;
我的问题是我的handleUserName
被调用了3次,我不明白为什么,即使callback
是我的UseEffect
的依赖列表,它应该是常数...
此外,由于useState
是异步的,即使用户登录了,第一次我的user
也是未定义的。
你知道我怎么解决这个问题吗?另外,你能告诉我我正在做的事情吗(检查用户是否已通过身份验证,对你来说听起来很奇怪?谢谢。
每次调用 handleUserName
时,它都会调用 setUser 和 setLoading,它们都会启动重新渲染。当 PublishContent 组件重新呈现(在本例中为两次)时,它将创建一个新函数并将其分配给 handleUserName,然后将其传递到您的 Navigation 组件和您的 useEffect,导致您的 useEffect 重新 运行 自依赖性已更改(重新渲染后的新功能)。要解决您的问题,您只需要像这样
const handleUserName = useCallback((e) => {
setUser(e)
setLoading(false)
}, [])
您也不应该在导航中调用 setUser。如果你需要访问它,你可以将它作为 prop
const PublishContent = () => {
const [loading, setLoading] = useState(true);
const [user, setUser] = useState(null);
const handleUserName = useCallback(e => {
setUser(e);
setLoading(false);
}, [])
return (
<div>
<Navigation callback={handleUserName} user={user} />
{
!loading && <div>{user ? <div>CONNECTED</div> : <div> NOT CONNECTED</div>} </div>
}
</div>
)
}
export default PublishContent;