如何修复`警告:文本内容不匹配。服务器:“一些数据”客户端:“正在加载...”`

rre*_*err 13 apollo reactjs graphql server-side-rendering react-apollo

我在 SSR 应用程序的初始加载时收到此错误:Warning: Text content did not match. Server: "SOME DATA" Client: "Loading..." 如何在不将loading标志设置为 true 的情况下初始化应用程序的 客户端?

我正在使用 react、express 和 apollo 设置 SSR。我从渲染器服务器获得了一个正确渲染的 HTML 数据,但是当客户端包加载时,它试图重新获取数据。Hydration 已设置,并且来自渲染器服务器的所有数据都被注入到页面的 HTML 中。

/index.js

<Query query={GET_USERS} variables={queryVariables}>
    {({
        loading,
        error,
        data
    }) => {
        if (loading) return <p>Loading...</p>;
        if (error) return `Error: ${error}`;
        return data.users.map(user => <p key={user.id}>{user.login}</p>);
    }}
</Query>
Run Code Online (Sandbox Code Playgroud)

/renderer.js

export default async (req, client) => {
    const serverSideApp = (
        <ApolloProvider client={client}>
            <StaticRouter location={req.path} context={{}}>
                <div>{renderRoutes(RoutesList)}</div>
            </StaticRouter>
        </ApolloProvider>
    );
        return getDataFromTree(serverSideApp).then(() => {
            const content = renderToString(serverSideApp);

            return `
                  <html>
                      <head></head>
                      <body>
                          <div id="root">${content}</div>
                          <script src="bundle.js"></script>
                          <script>

    window.__APOLLO_STATE__=${serialize(client.extract())}
                          </script>
                      </body>
                  </html>
            `;
    })
};
Run Code Online (Sandbox Code Playgroud)

/server.js

const app = express();

app.use(express.static("public"));

app.get("*", (req, res) => {
    const httpLink = createHttpLink({
        uri: "http://10.10.10.139:4000/",
        fetch
    });

    const client = new ApolloClient({
        link: httpLink,
        ssrMode: true,
        cache: new InMemoryCache()
    });

    renderer(req, client).then((html) => res.send(html));
});

app.listen(3000, () => {
    console.log("Server is up");
});
Run Code Online (Sandbox Code Playgroud)

/client.js

const httpLink = createHttpLink({
    uri: "http://10.10.10.139:4000/"
});

const client = new ApolloClient({
    link: httpLink,
    cache: new InMemoryCache().restore(window.__APOLLO_STATE__)
});

ReactDOM.hydrate(
    <ApolloProvider client={client}>
      <BrowserRouter>
        <div>{renderRoutes(RoutesList)}</div>
      </BrowserRouter>
    </ApolloProvider>,
    document.getElementById("root")
);
Run Code Online (Sandbox Code Playgroud)

我希望应用程序的客户端重新水化服务器端值,而不是loading在初始加载时触发标志。

Pet*_*ter 3

react-apollo文档来看,跳过 SSR 查询部分引入了一种机制,允许开发人员显式标记组件,以便它在服务器上加载该组件的数据,或者在服务器上以“正在加载”状态呈现该组件。

请尝试以下操作:

// index.js

<Query query={GET_USERS} ssr={false} variables={queryVariables}>
    {({
        loading,
        error,
        data
    }) => {
        if (loading) return <p>Loading...</p>;
        if (error) return `Error: ${error}`;
        return data.users.map(user => <p key={user.id}>{user.login}</p>);
    }}
</Query>
Run Code Online (Sandbox Code Playgroud)