useEffect 内的 setState 不会更新功能组件内的状态

iko*_*oza 1 reactjs google-cloud-firestore

记录 firestore 查询的结果会生成我需要的所有数据,但是使用 setPosts 将其存储在“posts”变量中会返回未定义的结果。我确信我错过了一些明显的东西......

\n
const Posts = () => {\n      const [posts, setPosts] = useState();\n    \n      \n      useEffect(() => {\n        db.collection('posts')\n        .get()\n        .then((data) => {\n          const results = data.docs.map((doc) => doc.data())\n          console.log(results);\n          // (8)\xc2\xa0[{\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}, {\xe2\x80\xa6}]\n          setPosts(results);\n          console.log(posts);\n          // undefined - why? \n        })\n        .catch((error) => {\n          console.error(error);\n        });\n      }, []);\n    \n      return ()};\n
Run Code Online (Sandbox Code Playgroud)\n

Jac*_*yef 6

console.log(posts)当您在 中执行操作时useEffect()posts这里引用的是您为第一次渲染定义的值,这是undefined因为您没有在 中指定默认值useState()

如果您将其放在console.log(posts)之外useEffect(),您将看到它将记录posts两次,一次用于第一个渲染,该渲染仍将注销undefined,另一次用于第二个渲染,在您执行此操作后触发setPosts()

可以这样想,每次状态更新时,React 都会通过渲染来更新你的 UI。效果与特定渲染相关。在您的原始代码中,您的组件渲染了 2 次。

  1. 初始渲染,也将运行效果。
  2. 第二次渲染,在setPosts(results)更新状态后触发。这里没有运行任何效果,因为您将其[]作为钩子的依赖项useEffect(),导致它只运行一次(当组件安装时)。

您正在console.log(posts)效果内部进行操作,这意味着它是初始渲染的一部分。想一想,posts初始渲染中的值是多少?它还是undefined!的新值posts仅在第二次渲染中可用。