我有一个组件,使用react-apollo
装饰器语法显示GraphQL查询的结果.查询接受一个参数,我想根据组件状态动态设置该参数.
请考虑以下简化示例:
import * as React from ‘react’;
import { graphql } from ‘react-apollo’;
import gql from ‘graphql-tag’;
const myQuery = gql`
query($active: boolean!) {
items(active: $active) {
}
}
`;
@graphql(myQuery)
class MyQueryResultComponent extends React.Component {
public render() {
return <div>
<input type=“checkbox” /* other attributes and bindings */ />
{this.props.data.items}
<div>;
}
}
Run Code Online (Sandbox Code Playgroud)
单击复选框时,我想重新提交查询,根据复选框的状态动态设置active
属性myQuery
.为简洁起见,我省略了复选框的处理程序和绑定,但是如何在状态更改时重新提交查询?
如果我们看一下todos示例,假设应用程序有多个视图(TodoList页面和另一个页面).
因此,不是直接引用todo项的数组的"todos",而是在状态/存储/缓存的顶层,它实际上只是具有某些自身状态的视图.
在该视图中,我们定义了待办事项列表和可见性过滤器 - 因此状态/存储/缓存不会如下所示:
{
todos: [TodoItem]
0:?TodoItem:0
completed: false
id: 0
text: "hh"
visibilityFilter: "SHOW_ALL"
}
Run Code Online (Sandbox Code Playgroud)
但是:
{
scenes: {
TodoList: {
todos: [TodoItem]
0:?TodoItem:0
completed: false
id: 0
text: "hh"
visibilityFilter: "SHOW_ALL"
},
SomeOtherView: { /* other state */}
}
}
Run Code Online (Sandbox Code Playgroud)
它甚至可能被孤立在它自己的数据"模块"中,就像这里提出的那样:https://medium.com/@alexmngn/how-to-use-redux-on-highly-scalable-javascript-applications-4e4b8cb5ef38:
{
scenes: {
TodoList: {
data: {
todos: [TodoItem]
0:?TodoItem:0
completed: false
id: 0
text: "hh"
}
visibilityFilter: "SHOW_ALL"
},
SomeOtherView: { /* other state */}
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序范围的状态将进一步存储一个级别: …
让我们假设我在React-Apollo中有以下GraphQL查询
const CurrentUserForLayout = gql`
query CurrentUserForLayout($avatarID: Int!) {
currentUser {
avatar_url(avatarID: $avatarID)
}
}
`;
const ProfileWithData = graphql(CurrentUserForLayout, {
options: { variables: { avatarID: 1 } },
})(Profile);
Run Code Online (Sandbox Code Playgroud)
现在,如果我想让我的React组件Profile
更改avatarID,
我该怎么办?
我是React和GraphQl的新手,我不太明白这里的连接:
graphql(CurrentUserForLayout, {
options: { variables: { avatarID: 1 } },
})(Profile);
Run Code Online (Sandbox Code Playgroud)
我真的需要另一个父组件ProfileWithData
来传递另一个父组件avatarID
吗?但是,如果ID由Profile组件操纵,我如何让Parent组件知道呢?
我在使用Graphql和Apollo Client时遇到了麻烦.
当我使用REST时,我总是创建不同的响应,如401代码,但在这里我不知道如何做类似的行为.
当我得到响应时,我希望它转到catch函数.我在前面有这个代码:
client.query({
query: gql`
query TodoApp {
todos {
id
text
completed
}
}
`,
})
.then(data => console.log(data))
.catch(error => console.error(error));
Run Code Online (Sandbox Code Playgroud)
有谁能够帮我?
使用:"react-apollo":"^ 1.4.3"
在父组件中,我使用GraphQL查询具有子项'fundQuarterlyMetric'的父节点'Fund'.这将以以下格式返回数据:
{
id
name
...
fundQuarterlyMetrics (orderBy: asAtDate_ASC) {
id
year
quarter
...
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试创建一个新的fundQuarterlyMetrics时,我必须使用更新功能(Apollo Client docs)更新react-apollo上的本地存储.它给了我一个错误:
Can't find field Fund({}) on object (ROOT_QUERY) {
"Fund({\"id\":\"cj57hpfips0x7014414u5tk8m\"})": {
"type": "id",
"id": "Fund:cj57hpfips0x7014414u5tk8m",
"generated": false
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我在console.log代理时,我可以看到基金和它的孩子们的数据....不知道该怎么做..
更新以下评论:
这是父组件数据请求:
export const fundPageQuery = gql`
query Fund($fundId: ID!) {
Fund(id: $fundId) {
id
name
....other variables
fundQuarterlyMetrics (orderBy: asAtDate_ASC) {
id
year
quarter
....other variables
}
}
Run Code Online (Sandbox Code Playgroud)
};
以下是我使用的选项:
var optionsForCreateFundMetric = {
update: (proxy, {data: {createFundMetrics}}) => …
Run Code Online (Sandbox Code Playgroud) 我使用React Router 4进行路由,使用Apollo Client进行数据获取和缓存.我需要根据以下标准实施PrivateRoute和重定向解决方案:
允许用户查看的页面基于用户状态,可以从服务器获取,也可以从缓存中读取.用户状态本质上是一组标志,用于了解用户在我们的渠道中的位置.例如国旗:isLoggedIn
,isOnboarded
,isWaitlisted
等.
如果用户的状态不允许他们在该页面上,则甚至不应该开始呈现页面.例如,如果不是isWaitlisted
,则不应该看到等待列表页面.当用户意外地发现自己在这些页面上时,应将其重定向到适合其状态的页面.
重定向也应该是动态的.例如,假设您在尝试之前查看用户个人资料isLoggedIn
.然后我们需要将您重定向到登录页面.但是,如果您isLoggedIn
不是isOnboarded
,我们仍然不希望您看到您的个人资料.因此,我们希望将您重定向到新手入门页面.
所有这些都需要在路由级别上进行.页面本身应该不知道这些权限和重定向.
总之,我们需要一个给出用户状态数据的库,可以
我已经在开发一个通用库,但它现在有它的缺点.我正在寻求关于如何解决这个问题的意见,以及是否有既定的模式来实现这一目标.
这是我目前的做法.这不起作用,因为getRedirectPath
需要的数据在OnboardingPage component
.
此外,我不能将PrivateRoute与可以注入计算重定向路径所需的道具的HOC包装起来,因为这不会让我将它用作Switch React Router组件的子节点,因为它不再是Route.
<PrivateRoute
exact
path="/onboarding"
isRender={(props) => {
return props.userStatus.isLoggedIn && props.userStatus.isWaitlistApproved;
}}
getRedirectPath={(props) => {
if (!props.userStatus.isLoggedIn) return '/login';
if (!props.userStatus.isWaitlistApproved) return '/waitlist';
}}
component={OnboardingPage}
/>
Run Code Online (Sandbox Code Playgroud) 我<Query>
在一个组件中使用Apollo Client ,在生命周期方法中更改状态时重新呈现该组件.我希望我的<Query>
组件重新运行查询,因为我知道数据已更改.在重新运行查询之前,Query组件似乎正在使用需要失效的缓存.
我正在使用一个不稳定的解决方法来缓存refetch
来自父组件中的渲染道具的回调,但感觉不对.如果有人有兴趣,我会在答案中发布我的方法.
我的代码看起来像这样.为简洁起见,我从查询中删除loading
并error
处理了一些其他细节.
class ParentComponent extends React.Component {
componentDidUpdate(prevProps) {
if (this.props.refetchId !== prevProps.refetchId) {
const otherData = this.processData() // do something
this.setState({otherData}) // this forces component to reload
}
}
render() {
const { otherData } = this.state
return (
<Query query={MY_QUERY}>
{({ data }) => {
return <ChildComponent gqlData={data} stateData={otherData} />
}}
</Query>
)
}
}
Run Code Online (Sandbox Code Playgroud)
如何强制<Query>
获取要传递的新数据<ChildComponent>
?
即使ParentComponent
在道具或状态发生变化时重新渲染,Query
也不会重新运行. …
我正在关注 youtube 上的 graphql 教程(https://www.youtube.com/watch?v=ed8SzALpx1Q at about 3hr 16min),其中部分内容compose
来自“react-apollo”。但是,我收到一个错误,因为新版本的 react-apollo 没有导出这个。
我在网上看了,我需要更换import { compose } from "react-apollo"
用import { compose } from "recompose"
,但这样做会产生错误TypeError: Cannot read property 'loading' of undefined
我也看到了,我应该取代反应,从阿波罗与进口import * as compose from "lodash"
,但是当我这样做,我得到其他错误,他说,× TypeError: lodash__WEBPACK_IMPORTED_MODULE_2__(...) is not a function
应用程序.js:
import React from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import BookList from "./components/BookList";
import AddBook from "./components/AddBook";
//apollo client setup
const client = …
Run Code Online (Sandbox Code Playgroud) 假设我有这样的模型
class Order(models.Model):
STATES = [
(1, 'Initiate'),
(2, "Brief"),
(3, "Planning"),
(4, "Price Negotiate"),
(5, "Executing"),
(6, "Pending"),
(7, "Completed"),
(8, "Canceled"),
(9, "Failed"),
(10, "Paid"),
]
state = models.PositiveSmallIntegerField(
choices=STATES,
default=1
)
Run Code Online (Sandbox Code Playgroud)
当我将这个模型与其Graphene对象类型的伴侣配对时
class OrderNode(graphene_django.DjangoObjectType):
class Meta:
model = Order
interfaces = (relay.Node,)
Run Code Online (Sandbox Code Playgroud)
OrderState!
创建具有名称的枚举类型.
我很关心
对于第一个问题,我有这个问题
{
customer(id: "Q3VzdG9tZXJOb2RlOjE=") {
name
orders {
edges {
node {
state
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
它给了我一个像A_1
和的奇怪的状态值A_2
.我期待它给我一些有意义的价值,比如"Initiate".如何获得kv对enum的值?
对于第二个问题,如果我想向用户提供此枚举的可能值列表,我该怎么办?
在我的组件中,我有以下代码:
componentDidMount () {
// Setup subscription listener
const { client, match: { params: { groupId } } } = this.props
client.subscribe({
query: HOMEWORK_IN_GROUP_SUBSCRIPTION,
variables: { groupId },
}).subscribe({
next ({ data }) {
const cacheData = client.cache.readQuery({
query: GET_GROUP_QUERY,
variables: { groupId },
})
const homeworkAlreadyExists = cacheData.group.homeworks.find(
homework => homework._id == data.homeworkInGroup._id
)
if (!homeworkAlreadyExists) {
client.cache.writeQuery({
query: GET_GROUP_QUERY,
variables: { groupId },
data: { ...cacheData,
group: { ...cacheData.group,
homeworks: [ ...cacheData.group.homeworks,
data.homeworkInGroup,
],
},
},
})
} …
Run Code Online (Sandbox Code Playgroud)