From 004aea7fd90242c1bd79c92309167eb4577599e7 Mon Sep 17 00:00:00 2001 From: l1b3r_- Date: Thu, 23 Dec 2021 18:56:27 +0000 Subject: [PATCH] feat: add fetcher and hook --- .storybook/preview.tsx | 6 --- README.md | 72 ++---------------------------- package.json | 4 +- src/components/example/index.tsx | 75 ++++++++++++++++++++++++++++++-- src/contexts/example/index.ts | 25 ----------- src/hooks/example/index.test.ts | 20 --------- src/hooks/example/index.ts | 14 ------ src/hooks/useEmpathy/index.ts | 42 ++++++++++++++++++ src/index.ts | 13 +----- src/providers/example/index.tsx | 28 ------------ yarn.lock | 17 ++++++++ 11 files changed, 138 insertions(+), 178 deletions(-) delete mode 100644 src/contexts/example/index.ts delete mode 100644 src/hooks/example/index.test.ts delete mode 100644 src/hooks/example/index.ts create mode 100644 src/hooks/useEmpathy/index.ts delete mode 100644 src/providers/example/index.tsx diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 7679eb2..d391458 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,5 +1,3 @@ -import { ExampleProvider } from '../src'; - export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { @@ -9,7 +7,3 @@ export const parameters = { }, }, }; - -export const decorators = [ - (Story) => {Story()}, -]; diff --git a/README.md b/README.md index acbc99c..a1b6428 100644 --- a/README.md +++ b/README.md @@ -21,57 +21,6 @@
-### Bootstrap - -```ts -npx @ricardo-jrm/empathy -``` - -Boilerplate `React` project bootstrapped with all necessary configs and workflows - -
- -### Workflows - -Quality Assurance - -- Will lint code and run tests -- Runs on `pull_request` sync and `push` to `main` - -Release - -- Will create a GitHub release with auto generated versioning and changelog -- Will publish the package to the public NPM registry -- Runs on `push` to `main` and after the QA job - -Publish to GitHub (Public) - -- Will publish the package to the public GitHub registry -- Runs on `workflow_dispatch` - -
- -### Dev Dependencies - -- `React` -- `Typescript` -- `Prettier` -- `ESLint` -- `Commit Lint` -- `Lint Staged` -- `Husky` -- `Jest` -- `React Testing Library` -- `Storybook` -- `Webpack` -- `Semantic Release` - -
- ---- - -
- ### Install ```ts @@ -85,24 +34,9 @@ yarn add @ricardo-jrm/empathy ### Usage ```ts -// hook -import { useExampleHook, ExampleHookType } from '@ricardo-jrm/empathy'; - -// context -import { - ExampleContext, - useExampleContext, - ExampleContextType, -} from '@ricardo-jrm/empathy'; - -// component -import { - ExampleComponent, - ExampleComponentProps, -} from '@ricardo-jrm/empathy'; - -// provider -import { ExampleProvider, ExampleProviderProps } from '@ricardo-jrm/empathy'; +import { useEmpathy } from '@ricardo-jrm/empathy'; + +const { data, error, isLoading } = useEmpathy(endpoint); ```
diff --git a/package.json b/package.json index f2b0ce2..cd2f850 100644 --- a/package.json +++ b/package.json @@ -94,8 +94,10 @@ "webpack-cli": "^4.9.1" }, "dependencies": { + "axios": "^0.24.0", "react": "^17.0.2", - "react-dom": "^17.0.2" + "react-dom": "^17.0.2", + "swr": "^1.1.1" }, "peerDependencies": { "react": "^17.0.2", diff --git a/src/components/example/index.tsx b/src/components/example/index.tsx index fdf7a39..02257a8 100644 --- a/src/components/example/index.tsx +++ b/src/components/example/index.tsx @@ -1,4 +1,9 @@ -import React from 'react'; +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable no-console */ +import React, { useState, useEffect, useCallback } from 'react'; +import { fetcher, useEmpathy } from '../../hooks/useEmpathy'; + +const exampleEndpoint = 'https://jsonplaceholder.typicode.com/users/1'; /** * ExampleComponent props @@ -13,6 +18,68 @@ export interface ExampleComponentProps { /** * ExampleComponent */ -export const ExampleComponent = ({ text }: ExampleComponentProps) => ( - {text} -); +export const ExampleComponent = ({ text }: ExampleComponentProps) => { + const [fetchedData, fetchedDataSet] = useState(undefined); + + const fetchJson = useCallback(() => { + fetchedDataSet(undefined); + setTimeout(async () => { + try { + fetchedDataSet(await fetcher(exampleEndpoint)); + } catch (err) { + // eslint-disable-next-line no-console + console.warn(`Error fetching with fetcher "${exampleEndpoint}": `, err); + // eslint-disable-next-line no-console + console.error(err); + } + }, 3000); + }, []); + + useEffect(() => { + fetchJson(); + }, [fetchJson]); + + const { + data: empathyData, + error: empathyError, + isLoading: isLoadingEmpathy, + } = useEmpathy(exampleEndpoint); + + useEffect(() => { + console.log({ fetchedData }); + }, [fetchedData]); + + useEffect(() => { + console.log({ empathyData }); + }, [empathyData]); + + useEffect(() => { + console.log({ empathyError }); + }, [empathyError]); + + return ( +
+ {text} +
+ Fetch: {fetchedData ? fetchedData?.name : 'Loading...'} +
+
+ Empathy: {!isLoadingEmpathy ? empathyData?.name : 'Loading...'} +
+
+ +
+
+ ); +}; diff --git a/src/contexts/example/index.ts b/src/contexts/example/index.ts deleted file mode 100644 index b05f553..0000000 --- a/src/contexts/example/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { useContext, createContext } from 'react'; - -/** - * Context interface - */ -export interface ExampleContextType { - example: string; -} - -/** - * Initial value - */ -const init: ExampleContextType = { - example: 'init', -}; - -/** - * Example Context - */ -export const ExampleContext = createContext(init); - -/** - * useExampleContext - */ -export const useExampleContext = () => useContext(ExampleContext); diff --git a/src/hooks/example/index.test.ts b/src/hooks/example/index.test.ts deleted file mode 100644 index 33ad377..0000000 --- a/src/hooks/example/index.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { renderHook, act } from '@testing-library/react-hooks'; -import { useExampleHook } from '.'; - -describe('test example hook', () => { - it('should init as 69', () => { - const { result } = renderHook(() => useExampleHook(69)); - const [state] = result.current; - expect(state).toBe(69); - }); - it('should update to 1337', () => { - const { result } = renderHook(() => useExampleHook(69)); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [state, stateSet] = result.current; - act(() => { - stateSet(1337); - }); - const [newState] = result.current; - expect(newState).toBe(1337); - }); -}); diff --git a/src/hooks/example/index.ts b/src/hooks/example/index.ts deleted file mode 100644 index 172b731..0000000 --- a/src/hooks/example/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Dispatch, SetStateAction, useState } from 'react'; - -/** - * ExampleContextType - */ -export type ExampleHookType = [T, Dispatch>]; - -/** - * useExampleHook - */ -export const useExampleHook = (initialValue: T): ExampleHookType => { - const [state, stateSet] = useState(initialValue); - return [state, stateSet]; -}; diff --git a/src/hooks/useEmpathy/index.ts b/src/hooks/useEmpathy/index.ts new file mode 100644 index 0000000..0e858fc --- /dev/null +++ b/src/hooks/useEmpathy/index.ts @@ -0,0 +1,42 @@ +/* eslint-disable no-console */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import axios, { AxiosResponse, AxiosError } from 'axios'; +import useSWR from 'swr'; + +/** + * Fetcher function + */ +export const fetcher = (endpoint: string) => + axios.get(endpoint).then((res: AxiosResponse) => res.data); + +/** + * useEmpathy props + */ +export type UseEmpathyProps = string; + +/** + * useEmpathy return type + */ +export type UseEmpathyType = { + data: T | undefined; + error: any | undefined; + isLoading: boolean; +}; + +/** + * useEmpathy hook + */ +export const useEmpathy = (endpoint: UseEmpathyProps): UseEmpathyType => { + const { data, error } = useSWR(endpoint, fetcher); + + if (error) { + console.warn(`Error fetching "${endpoint}": `, { error }); + console.error(error); + } + + return { + data, + error, + isLoading: !error && !data, + }; +}; diff --git a/src/index.ts b/src/index.ts index d9c45d0..861e9f7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,2 @@ -export { ExampleComponent } from './components/example'; -export type { ExampleComponentProps } from './components/example'; - -export { useExampleHook } from './hooks/example'; -export type { ExampleHookType } from './hooks/example'; - -export { ExampleContext, useExampleContext } from './contexts/example'; -export type { ExampleContextType } from './contexts/example'; - -export { ExampleProvider } from './providers/example'; -export type { ExampleProviderProps } from './providers/example'; +export { fetcher, useEmpathy } from './hooks/useEmpathy'; +export type { UseEmpathyProps, UseEmpathyType } from './hooks/useEmpathy'; diff --git a/src/providers/example/index.tsx b/src/providers/example/index.tsx deleted file mode 100644 index 614f218..0000000 --- a/src/providers/example/index.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { useMemo } from 'react'; -import { ExampleContext, ExampleContextType } from '../../contexts/example'; - -/** - * ExampleProviderProps - */ -export interface ExampleProviderProps { - /** - * Prop - */ - children: JSX.Element; -} - -/** - * ExampleProvider - */ -export const ExampleProvider = ({ children }: ExampleProviderProps) => { - // eslint-disable-next-line arrow-body-style - const ctx = useMemo(() => { - return { - example: 'example', - }; - }, []); - - return ( - {children} - ); -}; diff --git a/yarn.lock b/yarn.lock index af0df8c..4998b2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4325,6 +4325,13 @@ axe-core@^4.3.5: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5" integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -7135,6 +7142,11 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@^1.14.4: + version "1.14.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" + integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -13367,6 +13379,11 @@ supports-hyperlinks@^2.0.0, supports-hyperlinks@^2.1.0: has-flag "^4.0.0" supports-color "^7.0.0" +swr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/swr/-/swr-1.1.1.tgz#f13346cc830d7950183af57b341bfabb4cc90d43" + integrity sha512-ZpUHyU3N3snj2QGFeE2Fd3BXl1CVS6YQIQGb1ttPAkTmvwZqDyV3GRMNPsaeAYCBM74tfn4XbKx28FVQR0mS7Q== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"