问题
I am developing an react-native application using Relay for working with graphql. Before earlier versions I have been using Relay classic with RootContainer and renderer following the 'sibelius' react-native-relay-example also combined with these two posts: first and second.
So I have changed the react-relay version from 0.10.0 to 1.0.0 and for starters put a simple query at first screen using relay modern implementation. I did not change babel-relay-plugin. When ever I run the app I getgraphql: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as 'graphql'
I am also a starter at developing react-native apps and overall using graphql so I have this constant feeling I am missing something not mentioned in the docs which I suppose to already know when working with react.
This is my .babelrc file:
{
"plugins": ["./data/babelRelayPlugin"],
"presets": ["react-native"]
}
babelRelayPlugin.js
const getBabelRelayPlugin = require('babel-relay-plugin');
const schemaData = require('./schema.json');
module.exports = getBabelRelayPlugin(schemaData.data);
I am creating a RelayEnvironment which I am importing to the QueryRenderer:
import {
Environment,
Network,
Store,
RecordSource
} from 'relay-runtime';
const fetchQuery = (operation, variables, cacheConfig, uploadables) => {
return (
fetch('https://../graphql', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then( response => {
return response.json();
}).catch( err => console.log(err) )
);
}
const source = new RecordSource();
const store = new Store(source);
const network = Network.create(fetchQuery);
const handlerProvider = null;
export const RelayEnvironment = new Environment({
handlerProvider,
network,
store,
});
This is my QueryRenderer in jsx:
<QueryRenderer
environment={ RelayEnvironment }
query={ graphql`query {
content(path: "/latest-updates"){
title
children{
entries{
key: id
title
flyTitle
teaser
mainImageObj{
path
}
}
}
}
}` }
render={ ({error, props}) => {
if(error){
console.log(error);
} else if(props) {
console.log(props);
return <Text> Done </Text> ;
} else {
console.log('loading...');
}
}}
/>
If I run this query in graphiql I do get the expected result.
回答1:
babel-relay-plugin
is now babel-plugin-relay
in Relay Modern, and the usage isn't the same anymore - see here.
You need 3 things now:
- Your schema in GraphQL notation, in a separate file (it is the string you pass to buildSchema)
yarn add -D babel-plugin-relay
- you do not need to make a custom one anymore- To install and run the
relay-compiler
in the background
Here is how it works:
- You pass your schema to the relay-compiler via command-line and run it on your sources:
relay-compiler --src ./src --schema path/schema.graphql
- The relay compiler generates definitions for your queries in a folder called
__generated__
next to your files - The
babel-plugin-relay
replaces your queries by arequire()
call to the corresponding generated GraphQL definition by the relay compiler
Example setup and usage
yarn add -D babel-plugin-relay relay-compiler
Directory structure
schema.graphql
src/
App.js
.babelrc
package.json
schema.graphql
type Query {
user: User!
}
type User {
name: String!
}
src/App.js
// ...
const myQuery = graphql`
query App_ExampleQuery {
user {
name
}
}
`;
// ...
.babelrc
{
"plugins": ["relay"]
}
package.json
...
"scripts": {
"relay": "relay-compiler --src ./src --schema ./schema.graphql --watch",
},
...
Then, run yarn relay
or npm run relay
in a separate terminal.
Start your app as usual.
来源:https://stackoverflow.com/questions/44283394/error-loading-graphql-with-react-relay-modern