无法读取未定义的 属性 'map' (ReactJS-Apollo-Graphql)
Cannot read property 'map' of undefined (ReactJS-Apollo-Graphql)
我正在尝试使用 React JS 创建一个虚拟项目,我从 SpaceX Graphql API 获取数据。我有两个组件(Home、Details),这两个组件都应该从 API 中获取数据。但是,我查询在 Home 组件中有效,但在 Details 组件中无效。我使用了完全相同的方法,但它似乎不起作用。请帮我解决这个问题。
如果需要,您可以在 https://github.com/affiqzaini/react-apollo-spacex 尝试整个过程。
这是我的主页组件:
import React from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
import { BrowserRouter, NavLink } from 'react-router-dom';
import Route from 'react-router-dom/Route';
import 'react-bulma-components/dist/react-bulma-components.min.css';
import './App.css';
import Details from './Details';
const POSTS_QUERY = gql`
{
rockets {
name
country
id
}
}
`;
function Home() {
return (
<BrowserRouter>
<Route
path='/'
exact
strict
render={() => {
return (
<div
className='tile is-ancestor'
style={{
justifyContent: 'space-evenly',
alignItems: 'center',
margin: 25
}}
>
<Query query={POSTS_QUERY}>
{({ loading, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
const { rockets } = data;
return rockets.map(post => (
<NavLink to={{ pathname: `/${post.id}` }}>
<div class='tile is-parent'>
<article
class='tile is-child box'
key={post.id}
style={{
backgroundColor: 'whitesmoke',
borderRadius: 10,
height: 400,
width: 300
}}
>
<figure
class='image container is-1by1'
style={{ marginBottom: 15 }}
>
<img
src={require(`./Images/${post.id.toString()}.jpg`)}
className='Rocket-Img'
alt='Rocket'
/>
</figure>
<h2>{post.name}</h2>
<h4>{post.country}</h4>
</article>
</div>
</NavLink>
));
}}
</Query>
</div>
);
}}
/>
<Route path='/:id' exact strict component={Details} />
</BrowserRouter>
);
}
export default Home;
这是我的详细信息组件,它不起作用:
import React from 'react';
import { useParams } from 'react-router';
import { Query, ApolloProvider } from 'react-apollo';
import gql from 'graphql-tag';
import ApolloClient from 'apollo-boost';
import './App.css';
function Details() {
const rocketId = useParams();
const QUERY_ROCKET = gql`
{
rocket(id: "${rocketId}") {
id
active
boosters
company
cost_per_launch
name
stages
success_rate_pct
type
wikipedia
first_flight
country
description
}
}
`;
return (
<Query query={QUERY_ROCKET}>
{({ loading, data }) => {
if (loading) {
return <p className='Loading'>Loading...</p>;
} else {
const { detailsData } = data;
return detailsData.map(post => (
<div>
<p>{post.id}</p>
</div>
));
}
}}
</Query>
);
}
export default Details;
这是我得到的错误:
Error Image
更新:
我发现我在两个查询中得到了不同类型的数据。在主页(有效)中,我得到了一组数据。在我的详细信息组件中,我得到了一个对象。这就是我不能使用地图功能的原因吗?
根据查询文档https://www.apollographql.com/docs/react/v2.5/essentials/queries/
在这之后你不需要使用 "else":
if (loading) return <p className='Loading'>Loading...</p>;
并且您不会在有效的 Home 组件中执行此操作。尝试在您的详细信息组件中也删除 "else":
<Query query={QUERY_ROCKET}>
{({ loading, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
const { detailsData } = data;
return detailsData.map(post => (
<div>
<p>{post.id}</p>
</div>
));
}}
</Query>
如果您要映射的返回数据仍然是对象形式,那么您需要将对象转换为数组。
Object.values(data.detailsData)
获取 的数组 值,或 Object.entries(data.detailsData)
获取键值对的数组,即 [[key1, value1], [key2, value2], ...[keyN, valueN]]
.
The Object.values()
method returns an array of a given object's own
enumerable property values, in the same order as that provided by a
for...in
loop.
The Object.entries()
method returns an array of a given object's own
enumerable string-keyed property [key, value]
pairs, in the same order
as that provided by a for...in
loop.
return Object.values(detailsData).map(post => (
<div>
<p>{post.id}</p>
</div>
));
我发现我得到的数据是对象形式而不是数组。要访问该对象,您可以使用上面的 DrewReese 方法或我发现更简单的这种方法:
*** 'rocket'是我对象的名字
return (
<Query query={QUERY_ROCKET}>
{({ loading, error, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
if (error) return `Error! ${error.message}`;
const detailsData = data.rocket;
return (
<div>
<p>{detailsData.id}</p>
<p>{detailsData.name}</p>
<p>{detailsData.company}</p>
<p>{detailsData.stages}</p>
<p>{detailsData.boosters}</p>
<p>{detailsData.cost_per_launch}</p>
</div>
);
}}
</Query>
我正在尝试使用 React JS 创建一个虚拟项目,我从 SpaceX Graphql API 获取数据。我有两个组件(Home、Details),这两个组件都应该从 API 中获取数据。但是,我查询在 Home 组件中有效,但在 Details 组件中无效。我使用了完全相同的方法,但它似乎不起作用。请帮我解决这个问题。
如果需要,您可以在 https://github.com/affiqzaini/react-apollo-spacex 尝试整个过程。
这是我的主页组件:
import React from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';
import { BrowserRouter, NavLink } from 'react-router-dom';
import Route from 'react-router-dom/Route';
import 'react-bulma-components/dist/react-bulma-components.min.css';
import './App.css';
import Details from './Details';
const POSTS_QUERY = gql`
{
rockets {
name
country
id
}
}
`;
function Home() {
return (
<BrowserRouter>
<Route
path='/'
exact
strict
render={() => {
return (
<div
className='tile is-ancestor'
style={{
justifyContent: 'space-evenly',
alignItems: 'center',
margin: 25
}}
>
<Query query={POSTS_QUERY}>
{({ loading, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
const { rockets } = data;
return rockets.map(post => (
<NavLink to={{ pathname: `/${post.id}` }}>
<div class='tile is-parent'>
<article
class='tile is-child box'
key={post.id}
style={{
backgroundColor: 'whitesmoke',
borderRadius: 10,
height: 400,
width: 300
}}
>
<figure
class='image container is-1by1'
style={{ marginBottom: 15 }}
>
<img
src={require(`./Images/${post.id.toString()}.jpg`)}
className='Rocket-Img'
alt='Rocket'
/>
</figure>
<h2>{post.name}</h2>
<h4>{post.country}</h4>
</article>
</div>
</NavLink>
));
}}
</Query>
</div>
);
}}
/>
<Route path='/:id' exact strict component={Details} />
</BrowserRouter>
);
}
export default Home;
这是我的详细信息组件,它不起作用:
import React from 'react';
import { useParams } from 'react-router';
import { Query, ApolloProvider } from 'react-apollo';
import gql from 'graphql-tag';
import ApolloClient from 'apollo-boost';
import './App.css';
function Details() {
const rocketId = useParams();
const QUERY_ROCKET = gql`
{
rocket(id: "${rocketId}") {
id
active
boosters
company
cost_per_launch
name
stages
success_rate_pct
type
wikipedia
first_flight
country
description
}
}
`;
return (
<Query query={QUERY_ROCKET}>
{({ loading, data }) => {
if (loading) {
return <p className='Loading'>Loading...</p>;
} else {
const { detailsData } = data;
return detailsData.map(post => (
<div>
<p>{post.id}</p>
</div>
));
}
}}
</Query>
);
}
export default Details;
这是我得到的错误: Error Image
更新: 我发现我在两个查询中得到了不同类型的数据。在主页(有效)中,我得到了一组数据。在我的详细信息组件中,我得到了一个对象。这就是我不能使用地图功能的原因吗?
根据查询文档https://www.apollographql.com/docs/react/v2.5/essentials/queries/ 在这之后你不需要使用 "else":
if (loading) return <p className='Loading'>Loading...</p>;
并且您不会在有效的 Home 组件中执行此操作。尝试在您的详细信息组件中也删除 "else":
<Query query={QUERY_ROCKET}>
{({ loading, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
const { detailsData } = data;
return detailsData.map(post => (
<div>
<p>{post.id}</p>
</div>
));
}}
</Query>
如果您要映射的返回数据仍然是对象形式,那么您需要将对象转换为数组。
Object.values(data.detailsData)
获取 的数组 值,或 Object.entries(data.detailsData)
获取键值对的数组,即 [[key1, value1], [key2, value2], ...[keyN, valueN]]
.
The
Object.values()
method returns an array of a given object's own enumerable property values, in the same order as that provided by afor...in
loop.
The
Object.entries()
method returns an array of a given object's own enumerable string-keyed property[key, value]
pairs, in the same order as that provided by afor...in
loop.
return Object.values(detailsData).map(post => (
<div>
<p>{post.id}</p>
</div>
));
我发现我得到的数据是对象形式而不是数组。要访问该对象,您可以使用上面的 DrewReese 方法或我发现更简单的这种方法:
*** 'rocket'是我对象的名字
return (
<Query query={QUERY_ROCKET}>
{({ loading, error, data }) => {
if (loading) return <p className='Loading'>Loading...</p>;
if (error) return `Error! ${error.message}`;
const detailsData = data.rocket;
return (
<div>
<p>{detailsData.id}</p>
<p>{detailsData.name}</p>
<p>{detailsData.company}</p>
<p>{detailsData.stages}</p>
<p>{detailsData.boosters}</p>
<p>{detailsData.cost_per_launch}</p>
</div>
);
}}
</Query>