0

我正在使用 Apollo 客户端实现一个通用反应应用程序,我面临一个问题,我无法从服务器端的本地状态获取正确的初始状态值,但它可以在客户端上运行。我需要的是在服务器和客户端上都获得正确的主题模式。

这是我的serverRenderer上的内容:

  const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
    ssrMode: true,
    link: createHttpLink({
      uri: process.env.GRAPHQL_ENDPOINT,
      credentials: 'same-origin',
      fetch,
    }),
    cache: new InMemoryCache({ fragmentMatcher }),
    ssrForceFetchDelay: 100,
    ...apolloConfigs,
  });

  const Application = sheets.collect(
    <ApolloProvider client={client}>
      <Provider store={res.locals.store}>
        <Router location={req.url} context={routerContext}>
          <HelmetProvider context={helmetContext}>
            <App />
          </HelmetProvider>
        </Router>
      </Provider>
    </ApolloProvider>
  );

  const cookies = new Cookies(req.headers.cookie);

  const DOMGenerator = (content: string): string => {
    const materialCSS = sheets.toString();
    const state = res.locals.store.getState();
    initialState.themeMode = cookies.get('themeMode');
    client.writeData({ data: initialState });
    const initialApolloState = client.extract();
    const doctype = '<!doctype html>';
    return (
      doctype +
      renderToStaticMarkup(
        <Html
          css={[res.locals.assetPath('bundle.css'), res.locals.assetPath('vendor.css')]}
          helmetContext={helmetContext}
          scripts={[res.locals.assetPath('bundle.js'), res.locals.assetPath('vendor.js')]}
          materialCSS={materialCSS.replace(/\r?\n|\r/g, '')}
          state={JSON.stringify(state)}
          initialApolloState={JSON.stringify(initialApolloState)}
        >
          {content}
        </Html>
      )
    );
  };

  try {
    const result = await renderToStringWithData(Application);
    return res.send(DOMGenerator(result));
  } catch (e) {
    console.error(e); // eslint-disable-line
    return res.send('500 Internal Server Error');
  }

我的App.tsx

const QUERY = gql`
  query MyTheme {
    themeMode @client
  }
`;

const App: React.FC<OwnProps> = () => {
  const { data } = useQuery(QUERY);
  const theme = Theme(data?.themeMode);
  const styles = Styles({ theme });

  return (
    <StylesProvider injectFirst>
      <ThemeProvider theme={theme} key={data?.themeMode}>
        <Helmet>
          <title>Example</title>
        </Helmet>
        <Global styles={styles.global} />
        <div>Example</div>
      </ThemeProvider>
    </StylesProvider>
  );
};

如果我在App.tsx上记录数据,它会在服务器上返回undefined但它会在浏览器上返回正确的值。

4

0 回答 0