Reputation: 14811
I am working on a React JS project. My app needs to consume GraphQL API. So I am using Apollo client for that. When I use the Query component with ApolloProvider component, it is throwing error. Following is my code.
This is my app.js
import React from "react";
import ReactDOM from "react-dom";
import { createBrowserHistory } from "history";
import { HashRouter, Route, Switch, Redirect } from "react-router-dom";
import AdminLayout from "./layouts/Admin";
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient, { gql } from 'apollo-boost';
const client = new ApolloClient({
uri: 'https://48p1r2roz4.sse.codesandbox.io',
});
const hist = createBrowserHistory();
ReactDOM.render(
<ApolloProvider client={client}>
<HashRouter history={hist}>
<Switch>
<Route path="/admin" render={(props) => <AdminLayout {...props} />} />
<Redirect to="/admin/dashboard" />
</Switch>
</HashRouter>
</ApolloProvider>,
document.getElementById("app")
);
As you can see I declare the Apollo client and assign it to the client prop of the ApolloProvider component.
I have a component called, RestaurantForm component that is using GraphQL Query component as follow.
import React from 'react';
import {Button, Card, CardBody, CardFooter, CardHeader, CardTitle, Col, Form, FormGroup, Input, Row} from "reactstrap";
import gql from 'graphql-tag';
import { Query } from 'react-apollo';
const EXCHANGE_RATES_QUERY = gql`
{
rates(currency: "USD") {
currency
rate
}
}
`;
class RestaurantForm extends React.Component {
render() {
return (
<Query query={EXCHANGE_RATES_QUERY}>
{({ data }) => {
<>
<div className="content">
<Row>
<Col md="4">
<Card className="card-user">
<div className="image">
<img
alt="..."
src={"assets/paper-dashboard/img/damir-bosnjak.jpg"}
/>
</div>
<CardBody>
<div className="author">
<a href="#pablo" onClick={(e) => e.preventDefault()}>
<img
alt="..."
className="avatar border-gray"
src={"assets/paper-dashboard/img/mike.jpg"}
/>
<h5 className="title">Chet Faker</h5>
</a>
<p className="description">@chetfaker</p>
</div>
<p className="description text-center">
"I like the way you work it <br />
No diggity <br />I wanna bag it up"
</p>
</CardBody>
<CardFooter>
<hr />
<div className="button-container">
<Row>
<Col className="ml-auto" lg="3" md="6" xs="6">
<h5>
12 <br />
<small>Files</small>
</h5>
</Col>
<Col className="ml-auto mr-auto" lg="4" md="6" xs="6">
<h5>
2GB <br />
<small>Used</small>
</h5>
</Col>
<Col className="mr-auto" lg="3">
<h5>
24,6$ <br />
<small>Spent</small>
</h5>
</Col>
</Row>
</div>
</CardFooter>
</Card>
</Col>
<Col md="8">
<Card className="card-user">
<CardHeader>
<CardTitle tag="h5">Edit Profile</CardTitle>
</CardHeader>
<CardBody>
<Form>
<Row>
<Col className="pr-1" md="5">
<FormGroup>
<label>Company (disabled)</label>
<Input
defaultValue="Creative Code Inc."
disabled
placeholder="Company"
type="text"
/>
</FormGroup>
</Col>
<Col className="px-1" md="3">
<FormGroup>
<label>Username</label>
<Input
defaultValue="michael23"
placeholder="Username"
type="text"
/>
</FormGroup>
</Col>
<Col className="pl-1" md="4">
<FormGroup>
<label htmlFor="exampleInputEmail1">
Email address
</label>
<Input placeholder="Email" type="email" />
</FormGroup>
</Col>
</Row>
<Row>
<Col className="pr-1" md="6">
<FormGroup>
<label>First Name</label>
<Input
defaultValue="Chet"
placeholder="Company"
type="text"
/>
</FormGroup>
</Col>
<Col className="pl-1" md="6">
<FormGroup>
<label>Last Name</label>
<Input
defaultValue="Faker"
placeholder="Last Name"
type="text"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col md="12">
<FormGroup>
<label>Address</label>
<Input
defaultValue="Melbourne, Australia"
placeholder="Home Address"
type="text"
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col className="pr-1" md="4">
<FormGroup>
<label>City</label>
<Input
defaultValue="Melbourne"
placeholder="City"
type="text"
/>
</FormGroup>
</Col>
<Col className="px-1" md="4">
<FormGroup>
<label>Country</label>
<Input
defaultValue="Australia"
placeholder="Country"
type="text"
/>
</FormGroup>
</Col>
<Col className="pl-1" md="4">
<FormGroup>
<label>Postal Code</label>
<Input placeholder="ZIP Code" type="number" />
</FormGroup>
</Col>
</Row>
<Row>
<Col md="12">
<FormGroup>
<label>About Me</label>
<Input
type="textarea"
defaultValue="Oh so, your weak rhyme You doubt I'll bother, reading into it"
/>
</FormGroup>
</Col>
</Row>
<Row>
<div className="update ml-auto mr-auto">
<Button
className="btn-round"
color="primary"
type="submit"
>
Update Profile
</Button>
</div>
</Row>
</Form>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
}}
{ null }
</Query>
)
}
}
export default RestaurantForm;
When I run my app and go to the RestaurantForm component page, I got the following error.
app.js:66453 Warning: Failed prop type: Invalid prop `children` of type `array` supplied to `Query`, expected `function`.
in Query (created by RestaurantForm)
in RestaurantForm (created by Context.Consumer)
in Route (created by Dashboard)
in Switch (created by Dashboard)
in div (created by Dashboard)
in div (created by Dashboard)
in Dashboard (created by Context.Consumer)
in Route
in Switch
in ApolloProvider
in Router (created by HashRouter)
in HashRouter
The thing is without using the Query component and ApolloProvider component if I just instantiate the client in the RestaurantForm component and query it in the componentDidMount hook, it is working. But I need to use ApolloProvider and Query components. What is wrong with my code and how can I fix it?
Upvotes: 3
Views: 720
Reputation: 84727
The Query
component above has two children:
{({ data }) => {...}
{ null }
Remove the { null }
so that you're only passing in one child (the function) to resolve the error.
The callback also needs to return
{({ data }) => {
return (
//here are your components
)
}}
Upvotes: 3
Reputation: 7680
The error normally means what's inside Query
is mal-formatted.
Here's a post https://github.com/apollographql/react-apollo/issues/2050
Maybe you have extra comma, or maybe your code wasn't working even without Query
.
Upvotes: 0