reactjs - 如何使用 Apollo Graphql 客户端和 React 解决“TypeError:无法读取未定义的属性“参数”?
问题描述
我正在尝试连接一个套牌 URL 以链接到卡片列表,类似于我在Traversy 的 SpaceX graphql demo上看到的那样。我收到错误TypeError: Cannot read property 'params' of undefined单击指向任一演示卡组的链接时。
这是我在服务器之上构建的 React 客户端,使用 Apollo 和 GraphQL 连接到我的功能性 PostgreSQL 数据库。我已经将问题定位为这些行,以及道具是如何通过 React 和 Apollo 传递的。请注意,我是 GraphQL 和 Apollo 的初学者,这是我使用 React 的第一个真正项目,因此任何理解该过程的指导将不胜感激。
let { id } = this.props.match.params;
id = parseInt(id);
甲板 index.js
import React, { Component, Fragment } from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import Loading from "../../Loading";
import DeckItem from "./DeckItem";
const GET_DECKS = gql`
query DeckQuery {
decks @connection(key: "DeckConnection") {
edges {
id
deckName
createdAt
cards {
id
front
}
}
}
}
`;
class Decks extends Component {
render() {
return (
<Fragment>
<h1>Deck</h1>
<Query query={GET_DECKS}>
{({ data, error, loading }) => {
if (loading) {
return <Loading />;
}
if (error) {
return <p>Error</p>;
}
const decksToRender = data.decks.edges;
return (
<Fragment>
{console.log(data)}
{decksToRender.map(deck => (
<DeckItem key={deck.id} deck={deck} />
))}
</Fragment>
);
}}
</Query>
</Fragment>
);
}
}
export default Decks;
甲板项目 index.js
import React from "react";
import Moment from "react-moment";
import { Link } from "react-router-dom";
export default function DeckItem({ deck: { id, deckName, createdAt } }) {
return (
<div>
<div>
<h2>
<Link to={`/deck/${id}`}>{deckName}</Link>
</h2>
<p>Description coming soon...</p>
<h5>
Created on <Moment format="YYYY-MM-DD HH:mm">{createdAt}</Moment>
</h5>
</div>
</div>
);
}
卡片 index.js
import React, { Component, Fragment } from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import { Link } from "react-router-dom";
import Loading from "../../../Loading";
const CARDS_QUERY = gql`
query CardsQuery($id: ID!) {
deck(id: $id) {
id
deckName
cards {
id
front
back
}
}
}
`;
export class Cards extends Component {
render() {
let { id } = this.props.match.params;
id = parseInt(id);
return (
<Fragment>
<Query query={CARDS_QUERY} variables={{ id }}>
{({ data, error, loading }) => {
if (loading) {
return <Loading />;
}
if (error) {
return <p>Error</p>;
}
const {
id,
card: { front, back }
} = data.deck;
return (
<div>
<ul>
<h1>
<li>
<span>Id:</span> {id}
</li>
</h1>
<h4>Details</h4>
<li>Front: {front}</li>
<li>Back: {back}</li>
</ul>
<hr />
<Link to="/">Back</Link>
</div>
);
}}
</Query>
</Fragment>
);
}
}
export default Cards;
相关 React 路由路由
```
import { Router, Route } from "react-router-dom";
```
import FlashCardPage from "../FlashCards";
import Cards from "../FlashCards/Cards/CardsItem";
import * as routes from "../../constants/routes";
<Router>
```
<Route
exact
path={routes.FLASHCARDS}
component={() => <FlashCardPage />}
/>
<Route exact path={routes.CARDS} component={() => <Cards />} />
</div>
</Router>
我的路由文件中的路径是“/deck/:id”
控制台错误日志
react-dom.development.js:19782 Uncaught TypeError: Cannot read property 'params' of undefined
at Cards.render (index.js:23)
index.js:1452 The above error occurred in the <Cards> component:
in Cards (at App/index.js:42)
in component (created by Route)
in Route (at App/index.js:42)
in div (at App/index.js:19)
in Router (at App/index.js:18)
in App (at withSession.js:8)
in Query (at withSession.js:6)
in Unknown (at src/index.js:84)
in ApolloProvider (at src/index.js:83)
结果应该是一个显示卡片列表的套牌,“/deck/1”应该显示来自我的 PostgreSQL 服务器的 2 或 3 张卡片。目前我只能看到带有 url 的卡片组,但是点击后,它会立即抛出错误。其他 Graphql 函数工作正常,并且使用 Playground 查询工作得很好,所以看来我没有正确传递道具。需要任何其他信息,我很乐意提供。谢谢!
解决方案
Route
组件 fromreact-router-dom
使用render-prop模式来扩展它渲染的组件,提供它props
。[1]
props
它将这些( match
, location
, history
, 和staticContext
)转发给它在渲染时React.Component
传递给它的component
prop。[2]
在您定义的路由中,这不会传递给FlashCardPage
orCards
组件,因为有包装它们的无状态函数组件。
<Route exact path={routes.CARDS} component={() => <Cards />} />
这个无状态的函数组件是通过这些 props 传递的;您可以负责将这些转发props
到FlashCardPage
和Cards
组件。
<Route exact path={routes.CARDS} component={(props) => <Cards {...props} />} />
但是,我建议摆脱包装在中呈现的组件的无状态组件,Route
因为它是多余的。
<Route exact path={routes.CARDS} component={Cards} />
推荐阅读
- postgresql - 无法从在新卷中完成的还原加载数据库
- javascript - 11ty如何生成所有集合的列表
- mysql - 尝试启动 MySQL 服务器并获取“无法启动服务器:参数 2:
: 错误类型” - c++ - How to extract genotype information for each sample as a string from a VCF file using htslib?
- c++ - SFML 中按钮的 LinkedList 出现错误:Texture.cpp(98) 中的内部 OpenGL 调用失败
- menu - 如何在 sulu 管理界面添加新选项?
- ios - UIPanGestureRecognizer 下拉 UITableView
- html - Div 表带:将窗口大小调整到某个点后背景图像开始缩小
- javascript - D3.js - 使图例使用描述性字符串作为图例而不是数据值
- android - 即使在空活动时,匕首也会导致高内存使用