├── .gitignore
├── README.md
├── gif.gif
├── package.json
├── public
├── favicon.ico
├── index.html
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.test.tsx
├── App.tsx
├── index.css
├── index.tsx
├── react-app-env.d.ts
├── reportWebVitals.ts
└── setupTests.ts
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 | .idea
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Graphql + React [simple example](https://graphql-react-example.netlify.app/)
2 | ----
3 |
4 | Make query `GetExchangeRates` here https://48p1r2roz4.sse.codesandbox.io
5 | ```
6 | query GetExchangeRates {
7 | rates(currency: "USD") {
8 | currency
9 | rate
10 | }
11 | }
12 | ```
13 |
14 | 
15 |
16 | ---------
17 |
18 | ### Creat React typescript project
19 | ```shell
20 | $ npx create-react-app my-app --template typescript
21 | $ yarn add @apollo/client graphql
22 | ```
23 | ---------
24 |
25 | ### Connect Apollo Client to React with the ApolloProvider component. [src/index.tsx](src/index.tsx)
26 | ```tsx
27 | import {
28 | ApolloClient,
29 | InMemoryCache,
30 | ApolloProvider
31 | } from "@apollo/client";
32 |
33 | const client = new ApolloClient({
34 | uri: 'https://48p1r2roz4.sse.codesandbox.io',
35 | cache: new InMemoryCache()
36 | });
37 |
38 | render(
39 |
40 |
41 | ,
42 | document.getElementById('root'),
43 | );
44 | ```
45 |
46 | ---------
47 |
48 | ### Fetch data with useQuery that shares GraphQL data with your UI. [src/App.tsx](src/App.tsx)
49 |
50 | ```tsx
51 | import React from 'react';
52 | import './App.css';
53 | import {gql, useQuery} from "@apollo/client";
54 |
55 | const EXCHANGE_RATES = gql`
56 | query GetExchangeRates {
57 | rates(currency: "USD") {
58 | currency
59 | rate
60 | }
61 | }
62 | `;
63 |
64 | function ExchangeRates() {
65 | const {loading, error, data} = useQuery(EXCHANGE_RATES);
66 |
67 | if (loading) return
Loading...
;
68 | if (error) return Error :(
;
69 |
70 | return data.rates.map(({currency, rate}: { currency: string, rate: number }) => (
71 |
72 |
73 | {currency}: {rate}
74 |
75 |
76 | ));
77 | }
78 |
79 | function App() {
80 | return (
81 |
82 |
get "Currency Exchange Rates" using Apollo & Graphql
83 |
84 |
85 | );
86 | }
87 |
88 | export default App;
89 | ```
90 |
91 | ---------
92 |
93 | ## Official documentation [link](https://www.apollographql.com/docs/react/get-started/) or [https://graphql.org/](https://graphql.org/)
94 |
--------------------------------------------------------------------------------
/gif.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ebazhanov/react-graphql-example/b0a12bc00fb77cac5a22dfd5b0fdc2b44262e168/gif.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-graphql-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@apollo/client": "^3.5.5",
7 | "@testing-library/jest-dom": "^5.11.4",
8 | "@testing-library/react": "^11.1.0",
9 | "@testing-library/user-event": "^12.1.10",
10 | "@types/jest": "^26.0.15",
11 | "@types/node": "^12.0.0",
12 | "@types/react": "^17.0.0",
13 | "@types/react-dom": "^17.0.0",
14 | "graphql": "^16.0.1",
15 | "react": "^17.0.2",
16 | "react-dom": "^17.0.2",
17 | "react-scripts": "4.0.3",
18 | "typescript": "^4.1.2",
19 | "web-vitals": "^1.0.1"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": [
29 | "react-app",
30 | "react-app/jest"
31 | ]
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ebazhanov/react-graphql-example/b0a12bc00fb77cac5a22dfd5b0fdc2b44262e168/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Graphql and React simple example",
3 | "name": "Demonstration of GraphQL usage with React",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | h2, p{
2 | text-align: center;
3 | }
4 |
--------------------------------------------------------------------------------
/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './App.css';
3 | import {gql, useQuery} from "@apollo/client";
4 |
5 | const EXCHANGE_RATES = gql`
6 | query GetExchangeRates {
7 | rates(currency: "USD") {
8 | currency
9 | rate
10 | }
11 | }
12 | `;
13 |
14 | function ExchangeRates() {
15 | const {loading, error, data} = useQuery(EXCHANGE_RATES);
16 |
17 | if (loading) return Loading...
;
18 | if (error) return Error :(
;
19 |
20 | return data.rates.map(({currency, rate}: { currency: string, rate: number }) => (
21 |
22 |
23 | {currency}: {rate}
24 |
25 |
26 | ));
27 | }
28 |
29 | function App() {
30 | return (
31 |
32 |
Currency Exchange Rates
33 |
34 |
35 | );
36 | }
37 |
38 | export default App;
39 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | import {
8 | ApolloClient,
9 | InMemoryCache,
10 | ApolloProvider
11 | } from "@apollo/client";
12 |
13 | const client = new ApolloClient({
14 | uri: 'https://48p1r2roz4.sse.codesandbox.io',
15 | cache: new InMemoryCache()
16 | });
17 |
18 | render(
19 |
20 |
21 | ,
22 | document.getElementById('root'),
23 | );
24 |
25 | // If you want to start measuring performance in your app, pass a function
26 | // to log results (for example: reportWebVitals(console.log))
27 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
28 | reportWebVitals();
29 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------