在 Apollo Provider 中使用钩子

Using hooks with Apollo Provider

这是一个重现问题的 Codesandbox link: 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

您不能在组件的 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)
}

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

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