我最近一直在处理一些与钩子相关的问题,因为我一直在我的一个项目中实施钩子。我不断收到错误“渲染的钩子比上一次渲染时多”。
似乎让我的代码工作的唯一方法是将 useQuery 钩子放在所有其他钩子之后。然而,这是一个问题,因为我想用查询数据中的值填充一些状态值。
// code that doesn't error, but am not able to initialize state with query values
const [url, setUrl] = useState('')
const updateLink = useMutation(LINK_UPDATE_MUTATION, {
variables: {
id: props.id,
url
}
})
const { data, loading, error } = useQuery(LINK_QUERY, {
variables: {
id: props.id
}
})
if (loading) {
return <div>Loading...</div>
}
if (error) {
return <div>Error! {error.message}</div>
}
Run Code Online (Sandbox Code Playgroud)
对比
// code that errors with 'Rendered more hooks than during the previous render.'
const { …Run Code Online (Sandbox Code Playgroud) 我正在使用 React 钩子来获取 GraphQL 数据react-apollo并存储本地状态:
const [userData, setUserData] = useState({})
const { loading, error, data } = useQuery(USER_QUERY)
Run Code Online (Sandbox Code Playgroud)
但是,我想知道如何存储data到userData. 这是它应该如何工作:
useEffect(() => {
setUserData(data)
}, [Object.entries(data).length])
Run Code Online (Sandbox Code Playgroud) 我想知道是否有办法使缓存的项目在一定时间段(例如 24 小时)后过期。
我知道 Apollo Client v3 提供了诸如cache.evict和之类的方法cache.gc,这是一个很好的开始,我已经在使用;但是,我想要一种在给定时间段后删除缓存项目的方法。
我现在要做的就是向 Apollo 模式中的每个对象添加一个 TimeToLive 字段,当后端返回一个对象时,该字段将填充当前时间 + 24 小时(即 24 小时内的时间)。然后,当我在前端查询数据时,我检查返回数据的 TimeToLive 字段是否是将来的(如果不是,则意味着数据肯定是从缓存中检索的,在这种情况下我调用该函数refetch,这强制查询从服务器获取数据。但是,这似乎不是最好的方法,主要是因为我必须迭代返回数据中的每个结果并检查返回的对象是否已过期;如果是这样,所有内容都会重新获取。
我想到的另一个解决方案是使用React Native Queue之类的东西,并有一个后台任务来定期检查缓存和删除已过期的项目。但同样,我并不完全相信这个解决方案。
这里有一点背景信息:我正在构建一个烹饪/食谱应用程序 - 食谱/帖子缓存在设备上;然而,我担心的是,用户可以删除帖子,但缓存该帖子的其他人仍然可以看到它,因此,通过使缓存的项目过期,至少他们只能看到几个小时在其被移除之前。然而,它们可能是一个更好的方法来完成这一切,即让服务器与缓存的项目联系客户端(尽管在撰写本文时我无法想到任何低升力解决方案)
所以我试图在Next.js应用程序的客户端上拼接多个远程GraphCMS端点,在尝试/组合互联网上的每个示例之后,我已经把它带到了一个值得询问的地方.我的错误:
TypeError: this.getClient(...).watchQuery is not a function at GraphQL.createQuery
github repo在这里,你可以在上下文中看到这个initApollo.js:
import { ApolloClient } from 'apollo-client'
import {
makeRemoteExecutableSchema,
mergeSchemas,
introspectSchema
} from 'graphql-tools'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import fetch from 'node-fetch'
import { Observable, ApolloLink } from 'apollo-link'
import { graphql, print } from 'graphql'
import { createApolloFetch } from 'apollo-fetch'
let apolloClient = null
if (!process.browser) {
global.fetch = fetch
}
const PRIMARY_API = 'https://api.graphcms.com/simple/v1/cjfipt3m23x9i0190pgetwf8c'
const SECONDARY_API = …Run Code Online (Sandbox Code Playgroud) 我有一组突变触发某些类型的弹出窗口的本地状态.它们通常设置如下:
openDialog: (_, variables, { cache }) => {
const data = {
popups: {
...popups,
dialog: {
id: 'dialog',
__typename: 'Dialog',
type: variables.type
}
}
};
cache.writeData({
data: data
});
return null;
}
Run Code Online (Sandbox Code Playgroud)
我传入的默认值如下:
const defaults = {
popups: {
__typename: TYPENAMES.POPUPS,
id,
message: null,
modal: null,
menu: null,
dialog: null
}
};
Run Code Online (Sandbox Code Playgroud)
它们在我的React代码中的使用方式是使用Mutation包装器组件,如下所示:
const OPEN_ALERT_FORM = gql`
mutation AlertOpenDialog($type: String!) {
openDialog(type: $type) @client
}
`;
class Alert extends Component {
render() {
return (
<Mutation mutation={OPEN_ALERT_FORM} variables={{ …Run Code Online (Sandbox Code Playgroud) fetchMore发送查询时提供的函数updateQuery告诉 Apollo 如何使用结果更新其缓存(将其附加到您已有的内容上)。因此,轮询会重新获取您的初始查询并覆盖缓存,因此您将丢失分页以及fetchMore通过updateQuery.
我的问题:如何在保持良好用户体验的同时进行轮询和分页?(无订阅)
所以我需要一双新鲜的眼睛来帮助我!我刚刚开始使用 apollo 的新钩子,它们非常酷!但是,当我尝试传递变量时遇到问题,它返回未定义。
我在 graphql 服务器中有这个查询,它点击了 REST API,但目前我只返回标量 JSON
fetchRecipes(calories: String!, meal: String!): JSON
Run Code Online (Sandbox Code Playgroud)
在我的组件中:
const { data, loading, error } = useQuery(FETCH_RECIPES, {
variables: { calories: 500, meal: "beef" }
});
Run Code Online (Sandbox Code Playgroud)
const FETCH_RECIPES = gql`
query FetchRecipes($calories: String, $meal: String) {
fetchRecipes(calories: $calories, meal: $meal)
}
`;
Run Code Online (Sandbox Code Playgroud)
当我console.log(data)它回来时undefined,
然而,为什么这会起作用呢?(不通过 传递变量useQuery)
query {
fetchRecipes(calories: "500", meal: "beef")
}
Run Code Online (Sandbox Code Playgroud)
该组件如下所示:
const Recipes = () => {
const { data, loading, error } = useQuery(FETCH_RECIPES, { …Run Code Online (Sandbox Code Playgroud) 我只是使用 React-Native 作为客户端并检查服务器中的验证令牌。
当我的 jwt 令牌过期时,服务器会将其通知给客户端。
然后,apollo-client 捕获 graphQL 错误。
我想导航到注销用户并使其进入登录表单。
但是,我不知道如何在我的 graphQL forEach 块中做到这一点,
因为我无法在导航容器之外使用反应导航。
有谁知道解决这个问题吗?
...
const cache = new InMemoryCache()
await persistCache({
cache,
storage: AsyncStorage,
})
const clientState = (cache) =>
new ApolloClient({
link: ApolloLink.from([
...
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(
async ({ message, locations, path }) => {
console.log(
`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(
locations
)}, Path: ${path}`
)
if (
message ===
"You need to log in to perform this …Run Code Online (Sandbox Code Playgroud) 我想知道是否可以使用 InMemoryCache 的 typePolicies 来嵌套值 现在您可以定义平面字段策略
new InMemoryCache({
typePolicies: {
Query: {
fields: {
hello: {
read() {
return 'hello'
},
},
hola: {
read() {
return 'hola'
},
},
},
},
},
})
// query flat local field using apollo
const QUERY_USER_PAGE = gql`
query UserPage {
hello
hola
}
`
Run Code Online (Sandbox Code Playgroud)
如果我想要反映我的应用程序结构的 typePolicies 该怎么办,这似乎是一个很好的做法。
扁平结构在大型项目的扩展和维护方面会受到限制。
new InMemoryCache({
typePolicies: {
Query: {
fields: {
userPage: {
hello: {
read() {
return 'hello'
},
},
hola: {
read() {
return 'hola' …Run Code Online (Sandbox Code Playgroud) 我在我的 React 项目中使用 apollo-graphql ,并且收到以下错误
无效的挂钩调用。钩子只能在函数组件体内调用
这是我的代码
import React, { useEffect, useState, useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
// **************** COMPONENTS ****************
import { GET_MORTGAGE_JOURNEY } from "../../../../Graphql/Journeys/query";
export default function index() {
const insuranceId = useSelector((state) => state.mortgage.insuranceId);
// Panels Heading to show on all panels
useEffect(() => {
if (insuranceId) {
getMortgageData(insuranceId);
}
}, [insuranceId]);
function getMortgageData(insuranceId) {
const { loading, error, data } = useQuery(GET_MORTGAGE_JOURNEY, {
variables: { id: insuranceId },
}); …Run Code Online (Sandbox Code Playgroud) react-apollo ×10
apollo ×7
graphql ×5
reactjs ×5
javascript ×3
react-hooks ×3
caching ×1
next.js ×1
react-native ×1
typescript ×1