Взгляните на это:
/* eslint no-console: 0 */
import { ApolloProvider } from '@apollo/react-hooks';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import fetch from 'isomorphic-unfetch';
import Head from 'next/head';
import { useMemo } from 'react';
import PropTypes from 'prop-types';
let apolloClient = null;
/**
* Creates and configures the ApolloClient
* @param {Object} [initialState={}]
*/
// Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
const createApolloClient = (initialState = {}) => new ApolloClient({
ssrMode: typeof window === 'undefined', // Disables forceFetch on the server (so queries are only run once)
link: new HttpLink({
uri: process.env.CMS, // Server URL (must be absolute)
credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers`
headers: {
// Get JWT from Strapi Admin -> Plugins -> Documentation -> Retrieve your jwt token
authorization: `Bearer ${process.env.STRAPI_TOKEN}`,
},
fetch,
}),
cache: new InMemoryCache().restore(initialState),
});
/**
* Always creates a new apollo client on the server
* Creates or reuses apollo client in the browser.
* @param {Object} initialState
*/
const initApolloClient = (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 (typeof window === 'undefined') {
return createApolloClient(initialState);
}
// Reuse client on the client-side
if (!apolloClient) {
apolloClient = createApolloClient(initialState);
}
return apolloClient;
};
/**
* Creates and provides the apolloContext
* to a next.js PageTree. Use it by wrapping
* your PageComponent via HOC pattern.
* @param {Function|Class} PageComponent
* @param {Object} [config]
* @param {Boolean} [config.ssr=true]
*/
const withApollo = (PageComponent, { ssr = true } = {}) => {
const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => {
const client = useMemo(
() => apolloClient || initApolloClient(apolloState),
[apolloClient, apolloState],
);
return (
<ApolloProvider client={client}>
<PageComponent {...pageProps} />
</ApolloProvider>
);
};
// Set the correct displayName in development
if (process.env.NODE_ENV !== 'production') {
const displayName = PageComponent.displayName || PageComponent.name || 'Component';
if (displayName === 'App') {
console.warn('This withApollo HOC only works with PageComponents.');
}
WithApollo.displayName = `withApollo(${displayName})`;
}
if (ssr || PageComponent.getInitialProps) {
WithApollo.getInitialProps = async (ctx) => {
const { AppTree } = ctx;
// Initialize ApolloClient, add it to the ctx object so
// we can use it in `PageComponent.getInitialProp`.
ctx.apolloClient = initApolloClient();
const { apolloClient } = ctx;
// Run wrapped getInitialProps methods
let pageProps = {};
if (PageComponent.getInitialProps) {
pageProps = await PageComponent.getInitialProps(ctx);
}
// Only on the server:
if (typeof window === 'undefined') {
// When redirecting, the response is finished.
// No point in continuing to render
if (ctx.res && ctx.res.finished) {
return pageProps;
}
// Only if ssr is enabled
if (ssr) {
try {
// Run all GraphQL queries
const { getDataFromTree } = await import('@apollo/react-ssr');
await getDataFromTree(
<AppTree
pageProps={{
...pageProps,
apolloClient,
}}
/>,
);
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error);
}
// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind();
}
}
// Extract query data from the Apollo store
const apolloState = apolloClient.cache.extract();
return {
...pageProps,
apolloState,
};
};
}
return WithApollo;
};
withApollo.propTypes = {
apolloClient: PropTypes.string.isRequired,
apolloState: PropTypes.string.isRequired,
};
export default withApollo;
Как видите, в моем коде есть следующие строки:
import PropTypes from 'prop-types';
и
withApollo.propTypes = {
apolloClient: PropTypes.string.isRequired,
apolloState: PropTypes.string.isRequired,
};
И все же ESLint не может распознать это и выдает эту ошибку:
2:1 error Run autofix to sort these imports! simple-import-sort/sort
61:25 error 'apolloClient' is already declared in the upper scope no-shadow
61:25 error 'apolloClient' is missing in props validation react/prop-types
61:39 error 'apolloState' is missing in props validation react/prop-types
91:15 error 'apolloClient' is already declared in the upper scope no-shadow
Почему? Почему говорят, что apolloClient
и apolloState
отсутствуют в проверке реквизита, когда я четко убедился, что это не так? Я знаю, что могу просто подавить это с помощью /* eslint react/prop-types: 0 */
, но я не хочу этого делать. Я просто хочу понять, чего мне здесь не хватает.