使用 react-relay modern 加载 graphql 时出错

Error loading graphql with react-relay modern

我正在开发一个使用 Relay 的 react-native 应用程序来处理 graphql。 在早期版本之前,我一直在使用 Relay classic 和 RootContainer 以及遵循 'sibelius' react-native-relay-example also combined with these two posts: firstsecond.

所以我将 react-relay 版本从 0.10.0 更改为 1.0.0,对于初学者来说,使用中继现代实现在第一个屏幕上放置一个简单的查询。我没有更改 babel-relay-plugin。每当我 运行 我得到的应用程序 graphql: 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'

我也是开发 react-native 应用程序和整体使用 graphql 的初学者,所以我一直觉得我遗漏了文档中没有提到的东西,我想在使用 react 时已经知道了。

这是我的 .babelrc 文件:

{
  "plugins": ["./data/babelRelayPlugin"],
  "presets": ["react-native"]
}

babelRelayPlugin.js

const getBabelRelayPlugin = require('babel-relay-plugin');
const schemaData = require('./schema.json');
module.exports = getBabelRelayPlugin(schemaData.data);

我正在创建一个要导入到 QueryRenderer 的 RelayEnvironment:

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,
});

这是我在 jsx 中的 QueryRenderer:

        <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...');
            }
          }}
        />

如果我 运行 在 graphiql 中进行此查询,我会得到预期的结果。

babel-relay-plugin 在 Relay Modern 中现在是 babel-plugin-relay,并且用法不再相同 - see here.

你现在需要三样东西:

  • 您的 GraphQL 表示法模式,在一个单独的文件中(它是您传递给 buildSchema 的字符串)
  • yarn add -D babel-plugin-relay - 您不再需要定制
  • 在后台安装和运行relay-compiler

这是它的工作原理:

  • 您通过命令行将模式传递给中继编译器,并运行它在您的来源上:relay-compiler --src ./src --schema path/schema.graphql
  • 中继编译器在文件旁边名为 __generated__ 的文件夹中为您的查询生成定义
  • babel-plugin-relay 通过 require() 调用中继编译器生成的相应 GraphQL 定义来替换您的查询

设置和使用示例

yarn add -D babel-plugin-relay relay-compiler

目录结构

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",
},
...

然后,运行 yarn relaynpm run relay 在单独的终端中。
像往常一样启动您的应用程序。