如何在 Relay Modern 中取消订阅

Posted

技术标签:

【中文标题】如何在 Relay Modern 中取消订阅【英文标题】:How to unsubscribe in Relay Modern 【发布时间】:2018-02-14 09:19:48 【问题描述】:

我已按照How to GraphQL React + Relay 上的订阅教程进行操作,但没有提及您如何取消订阅 Relay Modern 网站。

任何帮助都会很棒。

更新 ----------

据 Lee Byron(see GitHub issue) 所说,您只需致电 dispose()requestSubscription()

对示例进行以下修改后:

./src/subscriptions/NewVoteSubscription.js(将return 添加到requestSubscription)

export default () => 
    const subscriptionConfig = 
    subscription: newVoteSubscription,
    variables: ,
    updater: proxyStore => 
        const createVoteField = proxyStore.getRootField('Vote')
        const newVote = createVoteField.getLinkedRecord('node')
        const updatedLink = newVote.getLinkedRecord('link')
        const linkId = updatedLink.getValue('id')
        const newVotes = updatedLink.getLinkedRecord('_votesMeta')
        const newVoteCount = newVotes.getValue('count')

        const link = proxyStore.get(linkId)
        link.getLinkedRecord('votes').setValue(newVoteCount, 'count')
    ,
    onError: error => console.log(`An error occured:`, error)
  

  return requestSubscription(
      environment,
      subscriptionConfig
  )

./src/components/LinkList.js(在组件上设置订阅,然后使用componentWillUnmountdispose()它)

componentDidMount() 
    this.subscription = NewVoteSubscription()


componentWillUnmount() 
    this.subscription.dispose()

这是我得到的错误:

Uncaught TypeError: Cannot read property 'dispose' of undefined
    at RelayObservable.js:94
    at doCleanup (RelayObservable.js:453)
    at Object.unsubscribe (RelayObservable.js:474)
    at RelayObservable.js:330
    at doCleanup (RelayObservable.js:453)
    at Object.unsubscribe (RelayObservable.js:474)
    at doCleanup (RelayObservable.js:450)
    at Object.unsubscribe [as dispose] (RelayObservable.js:474)
    at LinkList.componentWillUnmount (LinkList.js:18)
    at callComponentWillUnmountWithTimerInDev (react-dom.development.js:11123)
    at htmlUnknownElement.callCallback (react-dom.development.js:1309)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1348)
    at invokeGuardedCallback (react-dom.development.js:1205)
    at safelyCallComponentWillUnmount (react-dom.development.js:11131)
    at commitUnmount (react-dom.development.js:11421)
    at unmountHostComponents (react-dom.development.js:11362)
    at commitDeletion (react-dom.development.js:11392)
    at commitAllHostEffects (react-dom.development.js:12279)
    at HTMLUnknownElement.callCallback (react-dom.development.js:1309)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1348)
    at invokeGuardedCallback (react-dom.development.js:1205)
    at commitAllWork (react-dom.development.js:12384)
    at workLoop (react-dom.development.js:12695)
    at HTMLUnknownElement.callCallback (react-dom.development.js:1309)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:1348)
    at invokeGuardedCallback (react-dom.development.js:1205)
    at performWork (react-dom.development.js:12808)
    at batchedUpdates (react-dom.development.js:13262)
    at performFiberBatchedUpdates (react-dom.development.js:1656)
    at stackBatchedUpdates (react-dom.development.js:1647)
    at batchedUpdates (react-dom.development.js:1661)
    at Object.batchedUpdatesWithControlledComponents [as batchedUpdates] (react-dom.development.js:1674)
    at dispatchEvent (react-dom.development.js:1884)

【问题讨论】:

【参考方案1】:

并设置 RelayEnvironment

function setupSubscription(config, variables, cacheConfig, observer) 
  const query = config.text;

  const subscriptionClient = new SubscriptionClient(websocketURL, 
    reconnect: true
  );

  const client = subscriptionClient.request( query, variables ).subscribe(
    next: result => 
      observer.onNext( data: result.data );
    ,
    complete: () => 
      observer.onCompleted();
    ,
    error: error => 
      observer.onError(error);
    
  );

  return 
    dispose: client.unsubscribe
  ;

【讨论】:

【参考方案2】:

因为relay-modern@6 你需要返回 observable 否则它会因为这个错误而崩溃:RelayObservable: Unhandled Error TypeError: source.subscribe is not a function

而不是

return 
    dispose: client.unsubscribe
;

你需要回报

return Observable.create(() => 
  // return cleanup function
  return yourFunctionToCleanUp;
);

您可以从 relay-runtime 导入 Observable。

喜欢:

import 
  Observable,
 from 'relay-runtime';

所以当你在componentWillUnmount 中调用this.subscription.dispose() 时,实际上它会调用函数yourFunctionToCleanUp()

【讨论】:

以上是关于如何在 Relay Modern 中取消订阅的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeScript 中使用 Relay Modern(babel-plugin-relay 和 relay-compiler)?

是否可以使用 Relay Modern 命令式突变 API 取消链接记录?

如何使用 Relay Modern 突变进行文件上传?

如何在 Relay Modern 的父组件中最好地访问来自 QueryRenderer 的数据?

Relay Modern - 如何在没有 fragmentContainer 的情况下使用 fetchQuery

在 Relay Modern 中处理身份验证