【问题标题】:Using hooks with Apollo Provider使用 Apollo Provider 的钩子
【发布时间】:2020-10-14 19:50:57
【问题描述】:

这是重现问题的 Codesandbox 链接: https://codesandbox.io/s/boring-nash-svcj7?file=/src/index.js

我遇到了一个奇怪的问题。我有一个非常简单的设置 Apollo 设置,仅用于测试目的。它是这样的:

function App() {
  return (
    <ApolloProvider client={client}>
      <Main />
    </ApolloProvider>
  );
}

它只是一个简单的 ApolloProvider,为 App 组件提供客户端。 App 组件只有一行。

const Main = () => {
  const [data, setData] = useState();
  setData(1);
  return <div>Test</div>;
};

现在,当我刷新页面时,出现以下错误:

Too many re-renders. React limits the number of renders to prevent an infinite loop.

有人知道这里发生了什么吗?

为什么我不能在我的组件中使用一个简单的钩子?

这里是完整的代码:

import React, { useState } from "react";
import ReactDOM from "react-dom";

import ApolloClient from "apollo-client";
import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink } from "apollo-link-http";
import { ApolloProvider } from "@apollo/react-hooks";

const client = new ApolloClient({
  link: new HttpLink({
    uri: "https://api.graph.cool/simple/v1/swapi"
  }),
  cache: new InMemoryCache()
});

const Main = () => {
  const [data, setData] = useState();
  setData(1);
  return <div>Test</div>;
};

function App() {
  return (
    <ApolloProvider client={client}>
      <Main />
    </ApolloProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

有一个例子我正在关注它确实工作,所以我不确定为什么我的例子不是。

https://codesandbox.io/s/replace-previous-results-with-next-results-nuu6x?file=/src/FilmTitles.jsx:16-24

【问题讨论】:

  • setCursor 来自哪里?
  • 哎呀,我的意思是 setData

标签: reactjs react-hooks apollo react-apollo react-apollo-hooks


【解决方案1】:

你不能在组件的render 函数中使用setState。对于功能组件,它们的主体是render 函数。在这种情况下,setData 会更新触发重新渲染的状态,并在每次渲染时在无限循环中再次调用 setData

function App() {
    const [data, setData] = useState(0);
    setData(1); // this triggers re-render which is execution of App() which again calls setData(1)
}

【讨论】:

  • 这不是真的。是的,我们永远不应该在功能组件的主体中调用setState 。但这不是本案的原因。当你调用setState时,React 会检查状态是否真的改变了,如果是,它会重新渲染,如果不是,它不会。 data 是数字,所以它只会在数据从0 变为1 时重新渲染一次,当data1 并且您调用setData(1) 时,React 不会重新渲染组件。跨度>
  • 你错了@TonyNguyen 这是来自官方文档的引用 setState() 将始终导致重新渲染,除非 shouldComponentUpdate() 返回 false。 和 @987654321 @
  • 是的,但它正在处理这个例子,那为什么呢? codesandbox.io/s/…
  • @a53-416 因为setSkiponClick 事件的回调中被调用并且没问题
  • @TonyNguyen 我检查了链接并且有一个声明:如果您将 State Hook 更新为与当前状态相同的值,React 将退出而不渲染孩子或射击效果。请注意,React 在退出之前可能仍需要再次渲染该特定组件,因此它似乎确实渲染了......
【解决方案2】:

这样设置状态不是一个好主意,此时如果您只想尝试将setData 放入useEffect 并且不会再次出现此错误

  useEffect(() => {
    setData(1);
  }, [data]);

【讨论】:

    猜你喜欢
    • 2019-09-14
    • 2020-10-19
    • 2021-08-13
    • 2019-12-31
    • 1970-01-01
    • 2019-10-22
    • 2020-01-26
    • 1970-01-01
    • 2020-07-22
    相关资源
    最近更新 更多