我正在使用 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但它会在浏览器上返回正确的值。