Skip to content

Commit 3052e40

Browse files
committed
✨ add Fetch (react-query) example
1 parent 0b19eda commit 3052e40

File tree

14 files changed

+246
-31
lines changed

14 files changed

+246
-31
lines changed

playground/package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212
"storybook:build": "build-storybook"
1313
},
1414
"dependencies": {
15+
"@tailwindcss/forms": "^0.5.3",
16+
"axios": "^0.27.2",
1517
"clsx": "^1.2.1",
1618
"next": "12.2.5",
19+
"ramda": "^0.28.0",
1720
"react": "^18.2.0",
18-
"react-dom": "^18.2.0"
21+
"react-dom": "^18.2.0",
22+
"react-query": "^3.39.2"
1923
},
2024
"devDependencies": {
2125
"@babel/core": "^7.18.13",
@@ -30,6 +34,7 @@
3034
"@svgr/webpack": "^6.3.1",
3135
"@types/jest": "^29.0.0",
3236
"@types/node": "^18.7.14",
37+
"@types/ramda": "^0.28.15",
3338
"@types/react": "^18.0.18",
3439
"@types/react-dom": "^18.0.6",
3540
"autoprefixer": "^10.4.8",

playground/src/components/Blank/Blank.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,4 @@ const Blank = ({ name }: Props): JSX.Element => {
1616
);
1717
};
1818

19-
Blank.defaultProps = {};
20-
2119
export default Blank;

playground/src/components/Counter/Counter.tsx

+10-12
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
import React, { useState } from 'react';
1+
import React, { useEffect, useState } from 'react';
22

33
import Icon from 'components/Icon';
44
import { add, subtract } from 'utils';
55

66
export type CounterProps = {
7-
count: number;
7+
initial: number;
8+
onChange: (c: number) => void;
89
};
910

10-
const Counter = ({ count: defaultCount }: CounterProps): JSX.Element => {
11-
const [count, setCount] = useState(defaultCount);
11+
const Counter = ({ initial, onChange }: CounterProps): JSX.Element => {
12+
const [count, setCount] = useState(initial);
13+
14+
useEffect(() => {
15+
onChange(count);
16+
}, [count, onChange]);
1217

1318
return (
14-
<div
15-
id="counter"
16-
className="flex items-center justify-center w-full h-screen"
17-
>
19+
<div id="counter">
1820
<button
1921
type="button"
2022
onClick={() => setCount(subtract(count, 1))}
@@ -37,8 +39,4 @@ const Counter = ({ count: defaultCount }: CounterProps): JSX.Element => {
3739
);
3840
};
3941

40-
Counter.defaultProps = {
41-
count: 0,
42-
};
43-
4442
export default Counter;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.blank {
2+
@apply text-orange-500;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { ComponentMeta, ComponentStory } from '@storybook/react';
3+
4+
import Fetcher from './Fetcher';
5+
6+
export default {
7+
title: 'Demo/Fetcher',
8+
component: Fetcher,
9+
} as ComponentMeta<typeof Fetcher>;
10+
11+
const Template: ComponentStory<typeof Fetcher> = args => <Fetcher {...args} />;
12+
13+
export const Default = Template.bind({});
14+
Default.args = {
15+
name: 'John',
16+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, { useState } from 'react';
2+
import { isNil } from 'ramda';
3+
4+
import useAgify from 'hooks/useAgify';
5+
6+
const Fetcher = (): JSX.Element => {
7+
const [name, setName] = useState<string | null>(null);
8+
const { data, isLoading } = useAgify(name);
9+
10+
console.log(data);
11+
12+
return (
13+
<div>
14+
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
15+
<input
16+
type="text"
17+
name="name"
18+
className="block w-full border-gray-300 rounded-md shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
19+
placeholder="Your name..."
20+
onChange={e => setName(e.target.value)}
21+
value={name ?? ''}
22+
/>
23+
{!isLoading && !isNil(data) && (
24+
<p className="mt-4">
25+
{name}, your age is <b>{data.age}</b> 😇
26+
</p>
27+
)}
28+
</div>
29+
);
30+
};
31+
32+
export default Fetcher;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './Fetcher';

playground/src/components/Layout/Layout.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ type Props = {
77
};
88

99
const Layout = ({ children }: Props): JSX.Element => (
10-
// eslint-disable-next-line react-hooks/rules-of-hooks
1110
<div>
1211
<Icons />
1312
{children}
1413
</div>
1514
);
16-
Layout.defaultProps = {};
1715

1816
// For Storybook
1917
export const LayoutDecorator = (Story: FunctionComponent): JSX.Element => (

playground/src/hooks/useAgify.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useQuery, UseQueryResult } from 'react-query';
2+
import axios from 'axios';
3+
import { isNil } from 'ramda';
4+
5+
import AgifyResponse from '../types/agify-response';
6+
7+
const getAgify = async (name: string | null): Promise<AgifyResponse> => {
8+
// This axios method could be extract in a service to handle cancel tokens
9+
const { data } = await axios({
10+
url: `https://api.agify.io/?name=${name}`,
11+
method: 'GET',
12+
});
13+
14+
return data;
15+
};
16+
17+
const useAgify = (name: string | null): UseQueryResult<AgifyResponse, Error> =>
18+
useQuery(`agify_${name}`, () => getAgify(name), {
19+
enabled: !isNil(name),
20+
});
21+
22+
export default useAgify;

playground/src/pages/_app.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import React from 'react';
2+
import { QueryClient, QueryClientProvider } from 'react-query';
23
import type { AppProps } from 'next/app';
34

45
import 'styles/globals.css';
56

7+
const queryClient = new QueryClient();
8+
69
const MyApp = ({ Component, pageProps }: AppProps): JSX.Element => (
7-
<Component {...pageProps} />
10+
<QueryClientProvider client={queryClient}>
11+
<Component {...pageProps} />
12+
</QueryClientProvider>
813
);
914

1015
export default MyApp;

playground/src/pages/index.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import React from 'react';
22

3-
import Blank from 'components/Blank';
43
import Counter from 'components/Counter';
4+
import Fetcher from 'components/Fetcher';
55
import Layout from 'components/Layout';
66

77
const Home = (): JSX.Element => (
88
<Layout>
9-
<Counter />
10-
<Blank name="john" />
9+
<div className="flex flex-col items-center justify-center w-full h-screen">
10+
<div>
11+
<h2 className="my-4 text-xl font-bold">Counter example:</h2>
12+
<Counter initial={0} onChange={c => console.log(c)} />
13+
<h2 className="my-4 text-xl font-bold">Fetch example:</h2>
14+
<Fetcher />
15+
</div>
16+
</div>
1117
</Layout>
1218
);
1319

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type AgifyResponse = {
2+
name: string;
3+
age: number;
4+
count: number;
5+
};
6+
7+
export default AgifyResponse;

playground/tailwind.config.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ module.exports = {
66
theme: {
77
extend: {},
88
},
9-
plugins: [],
9+
plugins: [
10+
require('@tailwindcss/forms'),
11+
],
1012
}

0 commit comments

Comments
 (0)