3
votes

I'm studying the new (and awesome) GraphQL query components. There seems to be something wrong with my export statement. I'm getting the console error:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of App. .....App.js:30:4

.....

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. .....index.js/ index.js:77:4

Here's the code:

App.js

 1  import React from "react";
 2  import gql from "graphql-tag";
 3  import { graphql, Query } from 'react-apollo';
 4  import { withApollo } from "react-apollo";
 5  import ResolutionForm from "./ResolutionForm";
 6  import GoalForm from "./GoalForm";
 7  import RegisterForm from "./RegisterForm";
 8  import LoginForm from "./LoginForm";
 9  import Goal from "./resolutions/Goal";
10 
11  const RESOLUTIONS_QUERY = gql`
12    query Resolutions {
13      resolutions {
14        _id
15        name
16        completed
17        goals {
18          _id
19          name
20          completed
21        }
22      }
23      user {
24        _id
25      }
26    }
27  `;
28 
29  const App = ({ refetch }) => (
30      <Query
31          query={RESOLUTIONS_QUERY}
32          fetchPolicy={refetch ? 'cache-and-network': 'cache-first'}
33      >
34          {({ loading, data: {resolutions, client, user } }) => {
35              if (loading) return <span>loading....</span>
36              return (
37                  <div>
38                      {user._id ? (
39                          <button
40                              onClick={() => {
41                                  Meteor.logout();
42                                  client.resetStore();
43                              }}
44                          >
45                              Logout
46                          </button>
47                      ) : (
48                          <div>
49                              <RegisterForm client={client}/>
50                              <LoginForm client={client}/>
51                          </div>
52                      )}
53                      <ResolutionForm/>
54                      <ul>
55                          {resolutions.map(resolution => (
56                              <li key={resolution._id}>
57              <span
58                  style={{
59                      textDecoration: resolution.completed ? "line-through" : "none"
60                  }}
61              >
62                {resolution.name}
63              </span>
64                          <ul>
65                              {resolution.goals.map(goal => (
66                                  <Goal goal={goal} key={goal._id}/>
67                              ))}
68                          </ul>
69                          <GoalForm resolutionId={resolution._id}/>
70                      </li>
71                  ))}
72              </ul>
73                  </div>
74              );
75          }}
76      </Query>
77  );
78 
79  export default withApollo(App);

In terms of named vs default imports, here's the matching import statement, from index.js:

import.js

14 import App from "../../ui/App";
   .....
70 const ApolloApp = () => (
71     <ApolloProvider client={client}>
72         <App />
73     </ApolloProvider>
74 );
75 
76 Meteor.startup(() => {
77     render(<ApolloApp />, document.getElementById("app"));
78 });

How do I correct this error?

Thanks in advance to all for any info.

1
you should post all relevant files and the error should contain at least the line number - Armin Ĺ upuk
Line numbers have been added per your request. I believe all relevant files have been included. - VikR
This happens when a component is not a React component, string or function. Usually this is because one of them is undefined. The easiest way to debug this is to break in the render method and look at the components or alternatively console.log all of them (console.log(Query, RegisterForm, ...)). PS: I don't think you need the awaitQuery wrapping higher order component. - Herku
@Herku That was very helpful! By examining the data at that point, I discovered that my installed version of react-apollo did not include Query. After updating it the code ran without error. If you would like to enter your response as an answer, I will mark it as the accepted answer. - VikR

1 Answers

1
votes

This error message appears when a component is not a React component, string or function. Usually this is because one of them is undefined. The easiest way to debug this is to break in the render method and look at the components or alternatively console.log all of them (console.log(Query, RegisterForm, ...)).