【问题标题】:TypeError: Cannot read property 'getPosts' of undefined - useQuery hook, react Functional ComponentsTypeError:无法读取未定义的属性“getPosts”-useQuery 挂钩,反应功能组件
【发布时间】:2021-02-24 04:18:07
【问题描述】:

我确实尝试过搜索相同的问题,但所有这些问题都是有角度的或无关的,

我正在尝试使用 MongoDB、Express、React、Node、Graphql 和 Apollo 制作一个社交应用,我正在关注来自 freecodecamp 的视频:Link to the video 在那个视频中,一切正常,但在他部署的版本中,他遇到了和我一样的错误

react_devtools_backend.js:2450 类型错误:

无法读取未定义的属性“getPosts”

在 ae (Home.js:14) 在 Jo (react-dom.production.min.js:3274)

link to the deployed app

我的代码: 我正在删除一个指向我的 github 存储库的链接,其中包含整个项目:Link to github repo

Stack Overflow 引发了太多缩进问题,所以我在上面链接了我的 github 代码太多了

  • 我正在使用语义 UI 进行样式设置
  • 我正在使用 graphql 从 MongoDB 获取帖子
  • 用于渲染数据的 Apollo 客户端

这是我在 Home.js 中遇到的错误: 错误截图:

【问题讨论】:

  • 阅读文档! 'data' 可以在加载状态时未定义 ...if(loading) { return "loading" }; 在主返回之前(以及解构或对更深层次的 'data' 属性的任何访问)可防止此类错误
  • ehhhh,查看网络选项卡 - 响应包含错误 - 错误数据,错误结果...error 也可以从钩子派生,并且应该像加载一样阻止渲染
  • 对于 POST 应该是 200,总是……“不能为不可为空的字段 Post.username 返回 null。”第 54 项为空...渲染 jsoned 'posts'(或在返回之前插入'debugger')以检查它...禁用缩小,很难检查控制台中显示的点错误
  • if(data) console.log(posts); 返回前

标签: reactjs graphql react-hooks apollo-client react-functional-component


【解决方案1】:

改为让调试更简单:

常量 { 加载, 数据:{getPosts:帖子} } = useQuery(FETCH_POSTS_QUERY);

做:

const { data, loading, error } = useQuery(FETCH_POSTS_QUERY);
if(data) {
  console.log(data);
  const { getPosts: posts } = data;
}
if(error) {
  console.log(error);
  return "error"; // blocks rendering
}

这有效,但在数据存在时无效,但并非总是如此

“不是当数据”,“不是总是”???奇怪...'posts'只有在data存在时才能被定义...在未定义时访问它总是会失败...你必须检查'data'

您可以/应该仅在以下情况下呈现项目(帖子):

  • !loading

  • data != undefined - if(data)(data && 在 JSX 中

     {loading && <h1>Loading posts..</h1>}
     {data && (
       <Transition.Group>
         {posts &&
           posts.map((post) => (
             <Grid.Column key={post.id} style={{ marginBottom: 20 }}>
               <PostCard post={post} />
             </Grid.Column>
           ))}
       </Transition.Group>
     )}
    

【讨论】:

  • 感谢您的调试技巧起作用 现在我能够知道实际的错误是什么,我收到了网络错误,这是您写 return 的那一行的问题错误
【解决方案2】:

像这样使用这段代码

const { loading, data: { posts } = {} } = useQuery(FETCH_POSTS_QUERY);

【讨论】:

  • 可用 ... 仅用于一个深度级别
  • 有些人可能需要对object destructuring 进行更多解释,以便更好地理解您的答案。
  • 需要将数据定义为对象。将默认设置为空对象,这是旧的行为。
  • 旧的? HOC? ...如果您要重构为钩子,那么您可以使用新行为(未定义 data) - 您可以使用 if(!data) 作为一般未就绪条件,而不依赖于一些更深(也未定义)的道具
【解决方案3】:

您需要定义如下查询操作:

export const FETCH_POSTS_QUERY = gql`
  query GetPosts {
    getPosts {
      // fields
    }
  }
`

或者,您可以使用alias 轻松引用它们。

export const FETCH_POSTS_QUERY = gql`
  query GetPosts {
    posts: getPosts {
      // fields
    }
  }
`

const {
  loading,
  data: { posts } // uses alias directly. no need to rename
} = useQuery(FETCH_POSTS_QUERY);

【讨论】:

  • 现在我收到这个错误:TypeError: Cannot read property 'posts' of undefined
  • @GayatriDipali,更新了答案以明确显示完整的 gql 语句。
  • 它只为我工作了一分钟,现在它抛出了同样的错误
  • 可能与Home.js无关。也许SinglePost.js
【解决方案4】:
const { loading, data: { getPosts: posts } = {} } = useQuery(FETCH_POSTS_QUERY)

这应该可以解决问题

【讨论】:

    【解决方案5】:

    这将起作用

    在网格内写入 data.getPosts

    const { loading ,data , error } = useQuery(FETCH_POSTS_QUERY);

    如果(错误)返回Error! ${error.message}

        {loading ? (<h1>Loading posts...</h1>) 
        : (data.getPosts &&
          data.getPosts.map((post) => (
            <Grid.Column key={post.id} style= {{ marginBottom: 20}}>
              <PostCard post={post} />
            </Grid.Column>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-12
      • 2020-06-30
      • 2021-03-14
      • 2019-09-04
      • 1970-01-01
      • 2022-09-27
      • 2021-02-23
      • 2020-09-07
      相关资源
      最近更新 更多