【问题标题】:React Hook useEffect has a missing dependency: 'fetchComments'. Either include it or remove the dependency arrayReact Hook useEffect 缺少依赖项:'fetchComments'。包含它或删除依赖数组
【发布时间】:2020-09-26 04:36:37
【问题描述】:

为什么缺少依赖问题

const [ comments, setComment ] = useState([])

    const fetchComments = async () => {
        const res = await axios.get(`http://localhost:4001/posts/${postid}/comments`);
        setComment(res.data);
    }

    useEffect(() => {
        fetchComments();
    }, [postid]);

    console.log("IsArray", Array.isArray(comments)); // Returns me true, true, true then warning after warning it become false, false

为什么会有这样的行为我对帖子列表采用了相同的方法,它确实可以正常工作,但是使用特定 ID 获取它会向我发送错误。请指导

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    "postid" 不是 useEffect 挂钩的直接依赖项。所以要么将你的 fetchComments 函数移动到 useEffect 钩子中(如下所示)

    useEffect(() => {
       const fetchComments = async () => {
         const res = await axios.get(`http://localhost:4001/posts/${postid}/comments`);
         setComment(res.data);
       }
       fetchComments();
    }, [postid]);
    

    或添加 fetchComments 函数作为依赖项

    useEffect(() => {
       fetchComments();
    }, [fetchComments]);
    

    【讨论】:

    • 在第二个选项中,如果您不使用 useCallback 包装 fetchComments,您可能会递归地重新渲染。查看我的评论了解更多详情。
    【解决方案2】:

    这是 eslint 错误。因为useEffect在其回调函数中使用fetchComments,所以有办法解决。

    • 使用 useCallback 包装 fetchComments,然后将 fetchComments 包含在依赖项数组中

     const fetchComments = useCallback(async () => {
            const res = await axios.get(`http://localhost:4001/posts/${postid}/comments`);
            setComment(res.data);
        },[postid])
    
        useEffect(() => {
            fetchComments();
        }, [fetchComments]);
    • 在useEffect中定义函数

     useEffect(() => {
        const fetchComments = async () => {
          const res = await axios.get(
            `http://localhost:4001/posts/${postid}/comments`
          );
          setComment(res.data);
        };
        fetchComments();
     }, [postid]);
    • 禁用 eslint 错误(不推荐)

    const fetchComments = async () => {
        const res = await axios.get(
          `http://localhost:4001/posts/${postid}/comments`
        );
        setComment(res.data);
      };
      useEffect(() => {
        // eslint-disable-next-line
        fetchComments();
    }, [postid]);

    【讨论】:

    • 如果我尝试了 const renderComments = cmets.map(comment => { return (
    • {comment.content}
    • ) }) console.log (renderComments)它确实说 cmets.map 不是一个函数,但我做了 console.log(cmets 它确实显示数据)
  • @SunilDubey data 的类型是什么?你能把它包括在你的问题中吗?确保它是一个数组。
  • 是的,它是 66b2077b: Array(13) 0: {id: "aa1aba56", content: "teaser"} 1: {id: "d8efbcd1", content: "test"}
  • @SunilDubey 如果res.data 是一个数组,则只有一个地方可以调用setComment(res.data);,您将不会遇到该问题并且`console.log("IsArray", Array.isArray( cmets));` 必须为真。有了您发布的信息,如果res.data 是一个数组,comments 就不可能成为非数组类型。
  • 哦,我明白了,感谢您的支持,我返回的是对象而不是数组
  • 【解决方案3】:

    提供给useEffect的参数,意味着useEffect中的函数将在参数更改时运行。因此,useEffect 依赖于该参数。

    在这里,您提供 postid 作为 useEffect 的依赖项,但未在 useEffect 中使用它。这就是为什么 react 建议 postid 在这里没有用处,要么将 fetchComment 作为依赖项包括在内,要么从那里删除 postid

    因为,您希望在 postid 更改时运行 fetchcmets, 您可以像这样简单地重写它。

    const [ comments, setComment ] = useState([])
    
    const fetchComments = async (postid) => {
        const res = await axios.get(`http://localhost:4001/posts/${postid}/comments`);
        setComment(res.data);
    }
    
    useEffect(() => {
        fetchComments(postid);
    }, [postid]);
    

    【讨论】:

      猜你喜欢
      相关资源
      最近更新 更多
      热门标签