无法访问组件内部函数体内的状态值

Cannot access value of state inside function body that's inside component

我正在尝试访问函数 addToFeed() 中的状态变量 val。在addToFeed()里面的第一行代码中,console.log("Value of val: " + val) 行总是打印出“Value of val:”(表示找不到val,或者当时不存在观点)。 为什么会这样?我怎样才能在代码的那个点找到 val 的值? (val 的值确实存在 - 我只是无法访问它)。

代码的总体目标: 从 MongoDB 创建一个无限滚动的帖子列表,当用户滚动到页面底部时加载(此功能是工作,除非它不会加载最新的帖子,如果我的 val 变量从未传递给我的 API).

这是我的代码(代码下方简要说明了它对上下文的帮助):

import { useState, useEffect, useRef, useCallback } from "react";

export default function Feed() {
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(false);
    const [posts, setPosts] = useState([]);
    const [val, setVal] = useState(""); // VALUE I WANT TO ACCESS
    const [hasMore, setHasMore] = useState(true);

    const observer = useRef()
    const lastItemRef = useCallback(node => {
        if (loading) return;
        if (observer.current) observer.current.disconnect();
        observer.current = new IntersectionObserver(entries => {
            if (entries[0].isIntersecting) { 
                addToFeed();
            }
        });
        if (node) observer.current.observe(node);
    }, [loading]);

    useEffect(() => {
        return () => {
            setLoading(true);
            addToFeed();
            setLoading(false);
        }
    }, [])

    async function addToFeed() {
        console.log("Value of 'val': " + val) // 'val' CAN'T BE FOUND HERE (need it below for the body of my api call)
        try {
            if (hasMore) {
                await fetch("http://localhost:3000/api/load-forever-api", {
                    method: "POST",
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(val)
                }).then(res => res.json())
                    .then(data => {
                        setVal(data.posts[data.posts.length - 1].id)
                        setPosts(prev => {
                            return [...prev, ...data.posts]
                        })
                        setHasMore(data.hasMore)
                    });

            }
        }
        catch (error) {
            setError(true);
        }
    }

    // UI RETURNED BELOW

    if (loading) return <p>Loading...</p>
    if (error) return <p>Error</p>
    return (
        <>
            <h2>{`Value: ${val}`}</h2>
            {posts.map((item, index) => {
                if (posts.length === index + 1) {
                    return (
                        <div className="shaded-post" ref={lastItemRef} key={index}>
                            <h3>{item.title}</h3>
                            <p>{item.body}</p>
                            <p>{item.id}</p>
                            <br />
                        </div>
                    )
                } else {
                    return (
                        <div className="shaded-post" key={index}>
                            <h3>{item.title}</h3>
                            <p>{item.body}</p>
                            <p>{item.id}</p>
                            <br />
                        </div>
                    )
                }
            })}
        </>
    )

}

附加信息:

我的 API 调用 return 是一个包含 titlebodyid 字段的对象列表(MongoDB 调用)。 (例如:[{title: "ex1", body: "ex1", id: "123k8al29slkd"}, {title: "ex2", body: "ex2", id: "823jald8sj22"}]

如果我的 API 调用收到一个带有空白 val 变量的正文,它 return 是我的 MongoDB 集合中的前 4 个项目,如果它有一个id 变量,我将它用于 return 只是我的 MongoDB 集合中晚于该变量发布的项目(基本上,这允许增量无限滚动;加载前 4 个,然后如果用户滚动得足够低它将加载下一个 4,等等)

每次我触发 addToFeed() 函数时,我的 val 变量都会更新,并为其分配屏幕上最后一项(无限滚动)的 id 的值。

我的 addToFeed() 函数添加到我的 posts 状态,它呈现为我的 MongoDB 数据库中的项目列表。当用户滚动到页面底部时多次调用它会产生“无限滚动”的效果。

我有 3 个状态 UI 可以呈现:加载、错误和我的无限滚动项目列表 MongoDB。

您可以访问 valval 的默认值等于空字符串''

尝试将默认值更改为另一个值以查看它

  const [val, setVal] = useState("default val");

playground for your code

您没有获得 val 值的原因是当组件呈现时, lastItemRef 仍然具有旧的 addToFeed 函数引用。您应该在 lastItemRef useCallback 依赖项数组中传递 addToFeed。这样,每当组件呈现时,它将具有最新的 addToFeed 函数引用