【问题标题】:How to fix `Warning: Text content did not match. Server: "Some Data" Client: "Loading..."`如何修复`警告:文本内容不匹配。服务器:“一些数据”客户端:“正在加载...”`
【发布时间】:2019-06-05 11:39:48
【问题描述】:

我在初次加载 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>

/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>
            `;
    })
};

/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");
});

/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")
);

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

【问题讨论】:

  • 嘿,我也遇到了同样的问题 - 您找到解决此警告的解决方案了吗?
  • @Sidd 嗨!还没有。不得不切换到另一个项目,所以没有时间深入研究这个问题。你呢?你找到问题所在了吗?

标签: reactjs graphql apollo react-apollo server-side-rendering


【解决方案1】:

如果使用带有styled-jsx https://github.com/vercel/styled-jsx 的nextjs,如果您在style 标记上省略jsx 属性,则可能会出现此错误。

jsx 属性是必需的):

<style jsx>{`...`}</style>

不好(省略jsx属性):

<style>{`...`}</style>

省略jsx attr 将在浏览器控制台中抛出以下内容:

react-dom.development.js Warning: Text content did not match. Server: "..." Client: "..."

【讨论】:

    【解决方案2】:

    react-apollo 文档中,Skipping queries for 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>
    

    【讨论】:

      猜你喜欢
      • 2021-05-28
      • 2019-03-03
      • 2018-12-28
      • 1970-01-01
      • 2020-11-15
      • 2021-02-10
      相关资源
      最近更新 更多