在不调用 GraphQL 的情况下使用来自 RelayJS 的数据使用 React JS 过滤名称列表

Filtering a list of names with ReactJS using data from RelayJS without calling GrpahQL

我想知道是否可以过滤从 Relay 和 graphql-java 服务器收到的名称列表,而无需进行调用,无需对我的 GrpahQL 架构进行任何更改,并且仅为此目的使用 ReactJS。
---MobX 作为状态管理库可以是一个决定,但我应该首先存储所有中继结果。

买者自负:我也是 Relay 的新手,并且在这些相同的概念上苦苦挣扎。但是,鉴于 Relay 上的可访问信息相对匮乏,我认为尝试在此处列出关键概念会有所帮助。我的理解可能是错误的,所以如果有人在我的 code/reasoning 中发现错误,我会很高兴 comment/edit。

过滤对我来说也花了一段时间 'click'。这取决于您将用于过滤的数据保存在何处,但我们假设 name 字段位于您的 Users Type 上,并且查询如下所示:

viewer {
  allUsers {
    edges {
      node {
        name
      }
    }
  }
}

假设您的顶级 NameList 组件如下所示:

class NameList extends Component {
  render() {
    return (
      <div>
        {this.props.users.edges
          .map(u => {
            <NameItem name={u.node} />
           })
         }
      </div>
    )
  }
}

Relay.createContainer(NameList, {
  initialVariables: { first: 10 },
  fragments: {
    users: () => Relay.QL`
    fragment on Viewer {
      allUsers(first: $first) {
         edges {
           node {
             ${NameItem.getFragment('user')}
           }
          }
        }
      }
    ` 
  }
})

而您的 NameItem 设置很简单:

class NameItem extends Component {
      render() {
        return (
          <div>
            Name: {this.props.user.name}
          </div>
        )
      }
    }

Relay.createContainer(NameItem, {
  initialVariables: {},
  fragments: {
    user: () => Relay.QL`
    fragment on User {
      name
      }
    ` 
  }
})

考虑这里的通用模式:

列表组件

A List 组件在查询中获取顶级 Type 上的片段——在本例中,Viewer,来自 Relay container.

List 还在 User Type 级别代表其 Item 子级插入 fragment

换句话说,它捕获了一个应该传递给 Item 组件的 User 对象数组。

如果这不是 Relay,而是 Redux,则该组件可能只是将 state.users 传递给 Item 组件。您可以这样做,因为在某些时候,您已经从自己的后端手动提取所有 User 并将它们加载到 Redux 中。但是由于 Relay 为您进行了艰苦的思考,因此它需要的信息比 Redux 多一点点。

项目组件

这个就更简单了。它需要 User 类型的实体并呈现 name。除了语法之外,此处的功能与 Redux 设置中的类似组件没有太大区别。

所以真的,没有上面 Relay 的复杂性,您所拥有的只是要呈现的项目数组。在 vanilla React 中,您只需在 render().

中调用 .map() 之前(或期间)过滤数组

然而,对于 Relay,传递给 childfragmentparent 是不透明的——也就是说,List 传递了一个盲包给Item,所以无法根据fragment的内容决定是否传递。

这个人为设计的示例中的解决方案非常简单:只需剥离 parentchild 级别的 name 字段。请记住:Relay 是关于组件告诉 GraphQL 他们需要什么数据。您的 List 组件需要它打算过滤的任何字段——不多也不少。

如果我们修改上面的List容器:

...
users: () => Relay.QL`
    fragment on Viewer {
      allUsers(first: $first) {
         edges {
           node {
             name
             ${NameItem.getFragment('user')}
           }
          }
        }
      }
    ` 

然后我们更新 render 函数:

 <div>
        {this.props.users.edges
          .map(u => {
             if (u.node.name == "Harvey") {
               <NameItem name={u.node} />
             }
           })
         }
 </div>

然后我们实现了基本过滤,不需要 mobx、更多的服务器访问等