Reactjs 状态保持数百次刷新,即使使用效果良好

Reactjs 状态保持数百次刷新,即使使用效果良好,reactjs,react-hooks,Reactjs,React Hooks,所以我遵循Brad Traversy的React课程,但它有点旧,我在我自己的项目中使用hooks和modern React,但我有一个问题。当我进入用户的详细信息页面时,它调用一个函数从api获取该用户的信息。然而,事实证明,我调用这个函数数百次,甚至使用useffect。我将分享我的代码,但我不确定我做错了什么!如果有人能告诉我为什么这是重新渲染数千次,它肯定会有帮助。谢谢大家! 这是由Detail调用的函数(setLoading是一个useState函数,也是setSingleUser)

所以我遵循Brad Traversy的React课程,但它有点旧,我在我自己的项目中使用hooks和modern React,但我有一个问题。当我进入用户的详细信息页面时,它调用一个函数从api获取该用户的信息。然而,事实证明,我调用这个函数数百次,甚至使用useffect。我将分享我的代码,但我不确定我做错了什么!如果有人能告诉我为什么这是重新渲染数千次,它肯定会有帮助。谢谢大家!

这是由Detail调用的函数(setLoading是一个useState函数,也是setSingleUser)

const getUser = username => {
    setLoading(true);

    axios
        .get(
            `https://api.github.com/users/${username}?client_id=
    ${BLAHBLAH}&client_secret=
    ${BLAHBLAH}`,
        )
        .then(res => {
            axios
                .get(
                    `https://api.github.com/users/${username}/repos?per_page=5&sort=created:asc&
        client_id=${BLAHBLAH}&client_secret=
        ${BLAHBLAH}`,
                )
                .then(repores =>
                    setSingleUser({ ...res.data, repos: repores.data }),
                );
        });
    setLoading(false);
};
这就是我所说的细节

const Detail = ({ getUser, user, loading }) => {
const { username } = useParams();
useEffect(() => {
    getUser(username);
}, [username, getUser]);

我还尝试过使用空依赖项数组和无依赖项数组的useEffect,但它不喜欢这些选项中的任何一个。

之所以出现这种情况,是因为useEffect
[username,getUser]的第二个参数
。必须调用useEffect的依赖项数组直接在useEffect中调用,然后再次触发useEffect。因此,再次调用getUser。然后再次调用useEffect。因此它陷入了一个循环中。您几乎是在函数内部再次调用函数(getUser)每次调用(getUser)时都要调用的(useEffect)


您需要在useEffect中添加一个if条件,以确保仅在用户名为false、null或未定义时调用getUser()函数,或者您也可以更改传递给useEffect的数组。您甚至可以利用.then()中的
setSingleUser()
。并可以添加if检查中的值或数组中的值。

根据您的问题,您似乎在父组件中直接定义getUser并将其传递给子组件

由于您更新了getUser函数中的状态,父组件将重新呈现,并将创建一个新的getUser引用。现在您将
getUser
作为依赖项传递给useEffect,useEffect将在getUser函数更改时再次运行

要解决这个问题,您必须在父级中记住getUser函数,并且可以使用useCallback钩子来实现这一点

const getUser = useCallback(username => {
    setLoading(true);

    axios
        .get(
            `https://api.github.com/users/${username}?client_id=
    ${BLAHBLAH}&client_secret=
    ${BLAHBLAH}`,
        )
        .then(res => {
            axios
                .get(
                    `https://api.github.com/users/${username}/repos?per_page=5&sort=created:asc&
        client_id=${BLAHBLAH}&client_secret=
        ${BLAHBLAH}`,
                )
                .then(repores =>
                    setSingleUser({ ...res.data, repos: repores.data }),
                );
        });
    setLoading(false);
}, []);

一旦你这样做了,你的代码就可以正常工作了。只需在依赖项数组中包含用户名。删除函数
getUser
,因为当用户名被更改时,返回将被执行,当getUser被调用时,用户名将被更改,返回将再次被执行

尝试使用以下代码:

useEffect(() => {
    getUser(username);
}, [username]);

您能否在父组件中包含getUser的周围代码,以及如何将其传递给详细组件?感谢您的建议,这很有意义。如何解决此问题?数组是否需要为[username,getUser(username)]或者类似的东西?准确地说,这不是一个无限循环,而是一个递归。除了无限循环,当javascript实现的堆栈限制达到时,它会停止。请看这里:哇,这很有效,非常感谢!但是,我现在有一个警告:第12:5行:React Hook useEffect缺少依赖项:“getUser”。包括删除或删除依赖项数组。如果“getUser”更改太频繁,请找到定义它的父组件,并将该定义包装在useEffect/deps中。如何删除该定义?如果您没有在效果之外的任何位置使用此函数,则可以在useEffect中将其移动到此处,就像useEffect(()=>{const getUser=()=>{},[]);