0

私の目標は、同じものからの複数のネストされた兄弟を 1 つの呼び出しに結合するarraysことです。edgesRelay fragmentrender

Relayバックエンド データはコンテナ経由で配信されます(これも を使用react-router-relay)。

Tags複数の異なる から複数を表示するコンポーネント階層がありますUsers。トップレベルのクエリは次のようになります。

getUserGroup(id: 'abc') {
  users {
    edges { // array of arrays objects with nested arrays
      node {
        Tags {
          edges { // array of objects with target items
            node {
              tagName // target item
              id
            }
          }
        }
      }
    }
  }
}

結果は次のようになります (完全に平坦化された形式で):

  results = [['tagname1', 'tagname2'], [tagname3, tagname4]]

node Type現在、それぞれ独自の階層をレンダリングしますComponent。つまり、Tagmenu-> UserTagGroup-> TagItems(コードはこの投稿の下部にあります)。

これにより、すべてのタグが でグループ化されUser、最終的に次のようなリストがレンダリングされます。

User 1:
  - Tag 1
  - Tag 2
User 2:
  - Tag 3
  - Tag 4

私が達成したいのは、renderすべてUsersの ' タグが 2 番目の層、つまりTagMenu->TagItemsのような階層で一緒に混合されてレンダリングされる場所です。

User Tags
  - Tag 1
  ...
  - Tag 4

これまでに管理できる唯一の方法は、最上位のRelayコンテナーの結果からすべての配列を手動で抽出して、次のようなもの (疑似コード)と結合することです。

for each array in users.edges:
  for each array in node.Tags.edges:
    return node.tagName

これは、次の 2 つの理由から適切ではないようです。

  1. render()関数に詰め込むのは少し大変ですが、
  2. リレーで参照から保護できるかどうかは不明ですnulldefault props

...しかし、それは明らかに実行可能です。

私の質問は次のとおりRelayです。これを行う方法は何ですか? ライブラリがいかに自然にコンポーネントの構成につながるかを考えると、深くネストされた結果をより高いレベルで引き出し、それらを手動でシャッフルすることが最適であるとは思えません。ここに私のコンポーネントがあります:

// TagsMenu component, top level
class TagsMenu extends Component {
  render() {
    return (
      <div>
        {
          this.props.userGroup.users.edges.map(u => {
            return <UserTagGroup user={u.node} />
          })
        }
      </div>
    )
  }
}

fragment on UserGroup {
  users(first: 1000) {
    edges {
      node {
        ${UserTagGroup.getFragment('user')}
      }
    }
  }
}


// UserTagGroup, second component
class UserTagGroup extends Component {
  render() {
    return (
      <div>
        <h4>User:  {this.props.user.id}</h4>
        {
          this.props.user.Tags.edges.map(t => {
            return <TagMenuItem tag={t.node} />
          })
        }
      </div>
    )
  }
}
fragment on User {
  id
  listingTags(first: 1000) {
    edges {
      node {
        ${TagMenuItem.getFragment('tag')}
      }
    }
  }
}


// TagMenuItem, bottom level component. Renders 1 Tag.
class TagMenuItem extends Component {
  render() {
    return (
      <div>
        {this.props.tag.tagName}
      </div>
    )
  }
}
fragment on Tag {
  tagName
  id
}
4

1 に答える 1

0

あなたが説明してきたこと-「トップレベルのRelayコンテナーからすべての配列を手動で抽出して結合する」-は、しかし、行くべき道のように思えます.

問題がメソッドにこの関数があることrender()にある場合は、 state と method を組み合わせて使用​​することをお勧めしますcomponentWillReceiveProps()。目標は、this.props.users本当に変更された場合にのみ、平坦化されたリストを再計算することです。

論文に沿った何か:

class MyRootContainer extends Component {

  constructor(props) {
    super(props);

    this.state = {
      flattenedList: this.computeFlattenedListFromProps(this.props),
    };
  }

  componentWillReceiveProps(props) {
    if (this.props.users !== props.users) {
      this.setState({
        flattenedList: this.computeFlattenedListFromProps(props),
      });
    }
  }

  computeFlattenedListFromProps(props) {
    // Compute and return flattened list
  }

  render() {
    ...
  }
}
于 2017-01-12T22:46:52.740 に答える