如何在现代的Relay中将FragmentContainer与RefetchContainer结合起来

时间:2017-11-29 12:15:04

标签: reactjs relaymodern

我将一些Relay classis代码迁移到Relay modern。现在我很难迁移分页实现。我正在使用页面和偏移方法。这就是我现在所拥有的:

Game.jsx:

import React from 'react';
import ReactDOM from 'react-dom';
import {QueryRenderer, createFragmentContainer, createRefetchContainer, graphql} from 'react-relay';
import Player from './Player';

class Game extends React.Component {
    _loadPage(e) {
      e.preventDefault();
      this.props.relay.refetch({page: parseInt(e.target.dataset.page)}, null);
    }

    render() {
        return (
            <div>
                <h1>{this.props.game.name}</h1>
                <ul className="pagination">
                    {this.props.game.pages.map((page) => {
                        <li key={page.page}>
                            <a href="#" data-page={page.page} onClick={this._loadPage}>{page.page}</a>
                        </li>
                    })
                </ul>
                {this.props.game.players.map(player =>
                    <Player key={player.id} />
                )}
            </div>
        );
    }   
}

Game = createRefetchContainer(
  Game,
  {
      players: graphql`
        fragment Game_players on Game
        @argumentDefinitions(
          page: {type: "Int", defaultValue: 1},
          first: {type: "Int", defaultValue: 15}
        )
        {
          players(page: $page, first: $first) {
            id
            ...Player_player
          }
        }
    `
  },
  graphql`
    query GamePlayersRefetch_Query($page: Int!, $first: Int!) {
      game(id: $id) {
        ...Game_players @arguments(page: $page, first: $first)
      }
    }
  `
);


Game = createFragmentContainer(
    Game,
    graphql`
        fragment Game_game on Game
          @argumentDefinitions(
            page: {type: "Int", defaultValue: 1},
            first: {type: "Int", defaultValue: 15}
          ) {
          id
          name
          pages {
            page
          }
          ...game_players @arguments(page: $page, first: $first)
        }
    `
)


$(document).on("load turbolinks:load DOMContentLoaded", e => {
    let element = document.getElementById('game');
    ReactDOM.render(
          <QueryRenderer
            environment={environment}
            query={
              graphql`
                query gameQuery(
                    $id: ID!
                    $page: Int!
                    $first: Int!
                ) {
                      game(id: $id) {
                        ...Game_game @arguments(page: $page, first: $first)
                      }
                   }
            `
            }
            variables={{
              id: element.dataset.id,
              page: 1,
              first: 15
            }}
            render={({error, props}) => {
              if (props) {
                return <Game />
              } else {
                return <div>Loading.../div>
              }
            }}
          />,
          element
        );
    }

});

Player.jsx:

import React from 'react';
import {createFragmentContainer, graphql} from 'react-relay';

class Player extends React.Component {
    render() {
        <div className="player">
            <div class="player-name">{this.props.player.name}</div>
        </div>
    }
}


export default createFragmentContainer(
  Player,
  graphql`
    fragment Player_player on Player {
      id
    }
    `
);

我必须对FragmentContainer和RefetchContainer做错事,他们应该合并或者其他什么,但我不知道如何实现我想要的。有人可以开导我吗?

1 个答案:

答案 0 :(得分:0)

经过数小时的反复试验后,我自己想出来了。当一个人在StackOverflow上发布内容时总会发生这种情况...

这就是我必须做的事情:

Game = createRefetchContainer(
  Game,
  {
      game: graphql`
        fragment Game_game on Game
        @argumentDefinitions(
          page: {type: "Int", defaultValue: 1},
          first: {type: "Int", defaultValue: 15}
        )
        {
          id
          name
          players(page: $page, first: $first) {
            id
            ...Player_player
          }
        }
    `
  },
  graphql`
    query GamePlayersRefetch_Query($page: Int!, $first: Int!) {
      game(id: $id) {
        ...Game_players @arguments(page: $page, first: $first)
      }
    }
  `
);

现在不再需要FragmentContainer了。请注意,片段的名称已重命名为Game_game。