import { graphql } from "react-apollo";
import gql from 'graphql-tag';
import withData from "../../apollo/with-data";
import getPostsQuery from '../../apollo/schemas/getPostsQuery.graphql';
const renderers = {
paragraph: (props) => <Typography variant="body2" gutterBottom {...props} />,
};
const GET_POSTS = gql`${getPostsQuery}`;
const PostList = ({data: {error, loading, posts}}) => {
let payload;
if(error) {
payload = (<div>There was an error!</div>);
} else if(loading) {
payload = (<div>Loading...</div>);
} else {
payload = (
<>
{posts.map((post) => (
<div>
<div>{post.title}</div>
<div>{post.body}</div>
</div>
))}
</>
);
}
return payload;
};
export default withData(graphql(GET_POSTS)(PostList));
如您所见,当它在后台获取帖子时,它首先显示文本loading...
。我不想那样。我希望它已经来预先水合与提取的数据。
作为参考,我的Apollo初始化看起来是这样的:
// apollo/with-data.js
import React from "react";
import PropTypes from "prop-types";
import { ApolloProvider, getDataFromTree } from "react-apollo";
import initApollo from "./init-apollo";
export default ComposedComponent => {
return class WithData extends React.Component {
static displayName = `WithData(${ComposedComponent.displayName})`;
static propTypes = {
serverState: PropTypes.object.isRequired
};
static async getInitialProps(ctx) {
const headers = ctx.req ? ctx.req.headers : {};
let serverState = {};
// Evaluate the composed component's getInitialProps()
let composedInitialProps = {};
if (ComposedComponent.getInitialProps) {
composedInitialProps = await ComposedComponent.getInitialProps(ctx);
}
// Run all graphql queries in the component tree
// and extract the resulting data
if (!process.browser) {
const apollo = initApollo(headers);
// Provide the `url` prop data in case a graphql query uses it
const url = { query: ctx.query, pathname: ctx.pathname };
// Run all graphql queries
const app = (
<ApolloProvider client={apollo}>
<ComposedComponent url={url} {...composedInitialProps} />
</ApolloProvider>
);
await getDataFromTree(app);
// Extract query data from the Apollo's store
const state = apollo.getInitialState();
serverState = {
apollo: {
// Make sure to only include Apollo's data state
data: state.data
}
};
}
return {
serverState,
headers,
...composedInitialProps
};
}
constructor(props) {
super(props);
this.apollo = initApollo(this.props.headers, this.props.serverState);
}
render() {
return (
<ApolloProvider client={this.apollo}>
<ComposedComponent {...this.props} />
</ApolloProvider>
);
}
};
};
// apollo/init-apollo.js
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
import { onError } from 'apollo-link-error';
import { HttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-fetch';
let apolloClient = null;
// Polyfill fetch() on the server (used by apollo-client)
if (!process.browser) {
global.fetch = fetch;
}
const create = (headers, initialState) => new ApolloClient({
initialState,
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) => console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
));
}
if (networkError) console.log(`[Network error]: ${networkError}`);
}),
new HttpLink({
// uri: 'https://dev.schandillia.com/graphql',
uri: process.env.CMS,
credentials: 'same-origin',
}),
]),
ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
cache: new InMemoryCache(),
});
export default function initApollo(headers, initialState = {}) {
// Make sure to create a new client for every server-side request so that data
// isn't shared between connections (which would be bad)
if (!process.browser) {
return create(headers, initialState);
}
// Reuse client on the client-side
if (!apolloClient) {
apolloClient = create(headers, initialState);
}
return apolloClient;
}
更新:我尝试将https://github.com/zeit/next.js/tree/canary/examples/with-apollo的官方withApollo示例合并到我的项目中,但它在GetDataFromTree()
上抛出一个不变的错误:
对于/init/apollo.js
、/components/blog/postlist.jsx
和/pages/blog/jsx
文件,我使用了与repo示例中完全相同的代码。在我的具体案例中唯一的区别是我有一个显式的_app.jsx
,其内容如下:
/* eslint-disable max-len */
import '../static/styles/fonts.scss';
import '../static/styles/style.scss';
import '../static/styles/some.css';
import CssBaseline from '@material-ui/core/CssBaseline';
import { ThemeProvider } from '@material-ui/styles';
import jwt from 'jsonwebtoken';
import withRedux from 'next-redux-wrapper';
import App, {
Container,
} from 'next/app';
import Head from 'next/head';
import React from 'react';
import { Provider } from 'react-redux';
import makeStore from '../reducers';
import mainTheme from '../themes/main-theme';
import getSessIDFromCookies from '../utils/get-sessid-from-cookies';
import getLanguageFromCookies from '../utils/get-language-from-cookies';
import getUserTokenFromCookies from '../utils/get-user-token-from-cookies';
import removeFbHash from '../utils/remove-fb-hash';
class MyApp extends App {
static async getInitialProps({ Component, ctx }) {
let userToken;
let sessID;
let language;
if (ctx.isServer) {
ctx.store.dispatch({ type: 'UPDATEIP', payload: ctx.req.headers['x-real-ip'] });
userToken = getUserTokenFromCookies(ctx.req);
sessID = getSessIDFromCookies(ctx.req);
language = getLanguageFromCookies(ctx.req);
const dictionary = require(`../dictionaries/${language}`);
ctx.store.dispatch({ type: 'SETLANGUAGE', payload: dictionary });
if(ctx.res) {
if(ctx.res.locals) {
if(!ctx.res.locals.authenticated) {
userToken = null;
sessID = null;
}
}
}
if (userToken && sessID) { // TBD: validate integrity of sessID
const userInfo = jwt.verify(userToken, process.env.JWT_SECRET);
ctx.store.dispatch({ type: 'ADDUSERINFO', payload: userInfo });
}
ctx.store.dispatch({ type: 'ADDSESSION', payload: sessID }); // component will be able to read from store's state when rendered
}
const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
return { pageProps };
}
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentNode.removeChild(jssStyles);
}
// Register serviceWorker
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/serviceWorker.js'); }
// Handle FB's ugly redirect URL hash
removeFbHash(window, document);
}
render() {
const { Component, pageProps, store } = this.props;
return (
<Container>
<Head>
<meta name="viewport" content="user-scalable=0, initial-scale=1, minimum-scale=1, width=device-width, height=device-height, shrink-to-fit=no" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="194x194" href="/favicon-194x194.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/android-chrome-192x192.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#663300" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="msapplication-TileImage" content="/mstile-144x144.png" />
</Head>
<ThemeProvider theme={mainTheme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<Provider store={store}>
<Component {...pageProps} />
</Provider>
</ThemeProvider>
</Container>
);
}
}
export default withRedux(makeStore)(MyApp);
删除这个文件不是一个选项,因为我正在处理一些预加载cookie逻辑。
该回购可在https://github.com/amitschandillia/proost/tree/master/web上查阅
在使用Next.js和Apollo时,您希望实现2个关键的事情:SSR和缓存的网络数据。两者兼顾是一个艰难的平衡。但这是有可能的。
这样做的方法是:
我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se
我有一个客户端服务器的情况,每一方都在测量时间,但似乎有一个问题,即测量的时间不匹配。长话短说,这个想法是有一个倒计时,之后程序需要做事情。我在服务器端测量这个。但是,倒计时需要显示,所以我所做的是在客户端单独运行它。最终结果是,当服务器发送消息时,客户端显示为23秒,该消息表明时间倒计时为10分钟。 客户端为XNA,代码: 然后从可用时间中减去计时器,并显示出来。在服务器端,这种情况正在发生:
问题内容: 我尝试使用以下代码从服务器到客户端发送文件和目录列表。服务器正在从客户端接收消息,但我不知道服务器是否没有发送回结果或客户端是否不接受结果。 服务器端: 问题答案: 据我所见,您在客户端上做的同时在服务器上做。从服务器发送的字符串中没有行尾字符,因此客户端将永远无法完成。执行outqw.println()或添加到要发送的内容的末尾。话虽这么说,很难用一堆注释掉的东西来浏览未格式化的代码
我正在使用spring cloud Eureka配置一个应用程序。我在8761端口启动我的discovery应用程序,并在“http://localhost:8761”中到达控制台。 所以,我启动了我的客户端应用程序,它出现在eureka控制台的“应用程序”页面中。 第一个问题:我的客户机在properties config中使用了“server.port=0”,所以tomcat端口是随机启动的。
似乎服务器拒绝了wireshark输出中的tls协商,但我从代码中看不出原因。它是基于工作的代码,只是它被否决了,因此我用新的API更新。代码是开始。需要使用真实的证书。有人知道为什么服务器发送tcp FIN,ack吗? 我有以下服务器代码: 23 16.856111 sonymobi_7f:55:af intelcor_25:1d:fc ARP 42 10.1.10.100在84:c7:ea:7
websocket客户端(使用Autobahn/Python和Twisted)需要连接到websocket服务器:客户端需要向服务器提供其客户端证书,客户端需要检查服务器的证书。例如,这些证书是在Kubernetes minikube安装过程中创建的。特别地: 服务器证书(据我所知为X509格式) 客户端证书~/。minikube/客户。按键 我已经检查过,我可以成功地使用这些证书密钥使用发出库伯