Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Can';t使用上下文提供程序对未安装的组件执行React状态更新_Reactjs_Graphql_React Apollo_React Context - Fatal编程技术网

Reactjs Can';t使用上下文提供程序对未安装的组件执行React状态更新

Reactjs Can';t使用上下文提供程序对未安装的组件执行React状态更新,reactjs,graphql,react-apollo,react-context,Reactjs,Graphql,React Apollo,React Context,对于React项目,我使用多个上下文提供程序运行GraphQL查询,为所有或某些组件提供所需的数据。对于本例,我有一个BookProvider,它为特定用户查询所有书籍 export const BookProvider = ({ children }) => { // GraphQL query for retrieving the user-belonged books const { loading, data } = useQuery(gql`{ books {

对于React项目,我使用多个上下文提供程序运行GraphQL查询,为所有或某些组件提供所需的数据。对于本例,我有一个BookProvider,它为特定用户查询所有书籍

export const BookProvider = ({ children }) => {
  // GraphQL query for retrieving the user-belonged books
  const { loading, data } = useQuery(gql`{
    books {
        id,
        name,
        description
    }
  }
`, {
    pollInterval: 500
  })  

  if(!data?.books) return null

  return (
    <BookContext.Provider value={data?.books}>
      {!loading && children}
    </BookContext.Provider>
  )
}
数据的加载方式如下:

const { id, name } = useContext(BookContext)

同样,我有一个
AuthenticationProvider
,它包装了整个应用程序

export const MeQuery = gql`{ me { id, email } }`

export const AuthenticationProvider = (props) => {
  const { loading, data } = useQuery(MeQuery)

  if(loading) return null
  
  const value = {
    user: (data && data.me) || null
  }
    
  return <AuthenticationContext.Provider value={value} {...props} />
}
登录并设置用户对象时,没有问题,但是,当注销时(这是
仪表板上的一个组件),它会将我重新定向到登录页面,但我收到以下错误:

index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    at BookProvider (http://localhost:3000/static/js/main.chunk.js:2869:3)
    at Dashboard
    at Route (http://localhost:3000/static/js/vendors~main.chunk.js:85417:29)
    at PrivateRoute (http://localhost:3000/static/js/main.chunk.js:4180:14)
    at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:85619:29)
    at Router (http://localhost:3000/static/js/vendors~main.chunk.js:85052:30)
    at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:84672:35)
    at Router
对于注销,我使用以下代码:

export function useLogout() {
  const client = useApolloClient()

  const logout = useMutation(gql`mutation Logout { logout }`, { update: async cache => { 
    cache.writeQuery({ query: MeQuery, data: { me: null }})
        
    await client.resetStore()
  }})

  return logout
}

export default useLogout
它的调用方式类似于
const[logout]=useLogout()

问题

  • 为什么会发生这种错误
  • 如何解决这个问题
  • 在上下文提供程序中运行查询是一种好的做法吗

您的graphql查询挂钩似乎正在轮询数据,这将更新其内部状态,或者尝试更新,即使组件已卸载

我读过类似的问题(它看起来像一个bug,因为
useQuery
hook应该检测组件何时卸载并停止轮询)

其中一个似乎适合您的问题的解决方案是控制轮询,以便在组件卸载后可以停止轮询

看起来是这样的:

export const BookProvider=({children})=>{
//用于检索用户所属图书的GraphQL查询
const{loading,data,stopPolling,startPolling}=useQuery(gql`{
书{
身份证件
名称
描述
}
}`,{fetchPolicy:“仅限网络”})
React.useffect(函数managePolling(){
起动滚压(500)
return()=>stopPolling()
})
如果(!data?.books)返回空值
返回(
{!正在加载(&children}
)
}
它是否抑制警告


注意:不确定是否需要
{fetchPolicy:“仅网络”}
选项

我会再试一次;-)

您可以使用
useLazyQuery
,这似乎可以避免困扰
useQuery
的bug:

const[executeQuery,{data,loading}]=useLazyQuery(gql`${QUERY}`);
然后手动管理轮询:


useffect(函数managePolling(){
常量超时=空
const schedulePolling=()=>{
超时=设置超时(()=>{
executeQuery()
schedulePolling()
}, 500)
}
executeQuery()
schedulePolling()
return()=>clearTimeout(超时)
},[executeQuery])
(未经测试的代码,但您已经明白了)


这是在同一个线程()上建议的,所以可能您已经尝试过了…

不幸的是,它没有,我也在没有轮询的情况下尝试过。也不是Nessacy,您使用的是哪一版本的apollo客户端?
^3.3.12
。不过谢谢你的努力。
index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    at BookProvider (http://localhost:3000/static/js/main.chunk.js:2869:3)
    at Dashboard
    at Route (http://localhost:3000/static/js/vendors~main.chunk.js:85417:29)
    at PrivateRoute (http://localhost:3000/static/js/main.chunk.js:4180:14)
    at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:85619:29)
    at Router (http://localhost:3000/static/js/vendors~main.chunk.js:85052:30)
    at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:84672:35)
    at Router
export function useLogout() {
  const client = useApolloClient()

  const logout = useMutation(gql`mutation Logout { logout }`, { update: async cache => { 
    cache.writeQuery({ query: MeQuery, data: { me: null }})
        
    await client.resetStore()
  }})

  return logout
}

export default useLogout