React useEffect useContext - 上下文适用于某些组件,但不适用于动态路由

Posted

技术标签:

【中文标题】React useEffect useContext - 上下文适用于某些组件,但不适用于动态路由【英文标题】:React useEffect useContext - context works with some components, but not in dynamic route 【发布时间】:2021-07-06 11:48:20 【问题描述】:

我正在开发一个 React 博客应用程序,并在带有元数据的 Markdown 文件中发布帖子。元数据存储在 Firestore 中。包含内容的 .md 文件存储在 Cloud Storage 中。 App 组件使用 useEffect 从 Firestore 获取每个帖子的元数据并将其(对象数组)保存到 PostContext。这是 App 组件:

import React,  useEffect  from 'react'
import  BrowserRouter as Router, Switch, Route  from "react-router-dom"
import  firestore  from './firebase'
import  usePostsUpdate  from "./contexts/PostContext"
import PrivateRoute from "./components/auth/PrivateRoute"
...

function App() 
  const savePosts = usePostsUpdate()

  useEffect(() => 
    const postsRef = firestore.collection('metadata')
    postsRef.get()
      .then((snapshot) => 
        const posts = snapshot.docs.map((doc) => (
          ...doc.data()
        ))
        posts.sort((a, b) => b.postId - a.postId)
        savePosts(posts)
        console.log('App: in useEffect, posts.length', posts.length)
      )
  , [])

  console.log('APP')
  return (
    <React.Fragment>
      <Router>
        <Switch>
          <Route exact path="/" component=Home />
          ...
          <Route path="/all-posts" component=AllPostsPage />
          <Route path='/post/:id' render=props => <Post ...props /> />
          <Route path='/404' component=NotFoundPage />
        </Switch>

      </Router>
    </React.Fragment>
  );


export default App;

有 2 个问题。首先,关于语境。 'savePost()' 函数将数组保存到 PostContext,该数组已成功用于主页和“所有帖子”页面。但是,当我尝试使用“/post/:id”访问特定帖子时,从 PostContext 中提取的数组为空。不知何故,该数组似乎被重置为其默认(空)值,因此当我尝试访问它时出现错误(该数组包含用于访问 Cloud Storage 中检索所需内容所需的降价文件的 URL在页面上)。我找不到发生这种情况的原因。

其次,React 告诉我在 useEffect 中包含“savePosts”作为依赖项。但是当我这样做时,它只是循环。如果我删除依赖数组(我真的不想这样做),也会发生同样的事情。我没有可以添加满足 React 并且不会连续循环的依赖项。

【问题讨论】:

然后将你的依赖包含在 React.useEffect 的依赖数组中。 我试过了。如果我添加依赖项,组件会不断重新渲染。 【参考方案1】:

现在可以了。我手动输入 url 来测试路由。我继续设置动态路由(通过单击主页上的帖子摘要路由到 /post/id),现在上下文中的数组已正确填充。我不明白为什么在浏览器中手动输入“localhost:3000/post/1”与通过单击链接路由到同一 URL 的工作方式不同,但确实如此。

这并没有解决 React useEffect 警告的问题,但我可以忍受。

【讨论】:

以上是关于React useEffect useContext - 上下文适用于某些组件,但不适用于动态路由的主要内容,如果未能解决你的问题,请参考以下文章

TypeError: (0 , _react.useEffect) 不是函数

react--useEffect使用

UseEffect - React Hook useEffect 缺少依赖项:

React 延迟加载 useEffect

React Hook useEffect 缺少依赖项:'props' 由于 useEffect 中有一行

React - 是不是在 useEffect 中调用 API