-
Notifications
You must be signed in to change notification settings - Fork 3
05 Fetching
JP Barbosa edited this page Apr 18, 2021
·
4 revisions
code ./.env
REACT_APP_API=https://typescript-crud-api.herokuapp.com
#REACT_APP_API=http://localhost:4000
Obs.: To run the API locally checkout TypeScript CRUD API.
code ./src/hooks/useFetch.ts
import axios from 'axios';
import { useState, useEffect } from 'react';
import { Record } from '../interfaces/RecordEntities';
export const useFetch = <T extends Record>(path: string, options?: {}) => {
const [records, setRecords] = useState<T[]>([]);
const url = `${process.env.REACT_APP_API}/${path}`;
useEffect(() => {
const callFetchFunction = async () => {
const res = await axios.get<T[]>(url, { params: options });
setRecords(res.data);
};
callFetchFunction();
}, [url, options]);
return { records };
};
code ./src/App.tsx
...
import { ArticleIndex } from './pages/Article';
const App: React.FC = () => {
...
const renderSwitch = () => {
switch (page) {
case Page.Articles:
return <ArticleIndex />;
...
}
};
...
};
export default App;
code ./src/pages/Article/index.tsx
import { Article } from '../../interfaces/RecordEntities';
import { RecordIndex } from '../Record';
import { ArticleListItem } from './ListItem';
export const ArticleIndex: React.FC = () => {
const apiOptions = { relations: ['author'] };
return (
<RecordIndex<Article>
ListItem={ArticleListItem}
apiPath="articles"
apiOptions={apiOptions}
/>
);
};
code ./src/interfaces/PagesProps.ts
export interface RecordIndexProps<T> {
ListItem: React.FC<ListItemProps<T>>;
apiPath: string;
apiOptions: {};
}
code ./src/pages/Record/index.tsx
import { Record } from '../../interfaces/RecordEntities';
import { RecordIndexProps } from '../../interfaces/PagesProps';
import { useFetch } from '../../hooks/useFetch';
import { RecordList } from './List';
export const RecordIndex = <T extends Record>({
ListItem,
apiPath,
apiOptions,
}: RecordIndexProps<T>) => {
const { records } = useFetch<T>(apiPath, apiOptions);
return (
<div className="page">
<div className="content">
<RecordList<T> ListItem={ListItem} records={records} />
</div>
</div>
);
};
code ./src/interfaces/PagesProps.ts
...
export interface RecordListProps<T> {
ListItem: React.FC<ListItemProps<T>>;
records: T[];
}
code ./src/pages/Record/List.tsx
import { Record } from '../../interfaces/RecordEntities';
import { RecordListProps } from '../../interfaces/PagesProps';
import { usePage } from '../../contexts/Page';
export const RecordList = <T extends Record>({
ListItem,
records,
}: RecordListProps<T>) => {
const { page } = usePage();
return (
<div className="list">
<h2>{page}</h2>
<ul>
{records.map((record) => (
<li key={record.id}>
<ListItem record={record} />
</li>
))}
</ul>
</div>
);
};
code ./src/interfaces/PagesProps.ts
...
export interface ListItemProps<T> {
record: T;
}
code ./src/pages/Article/ListItem.tsx
import { Article } from '../../interfaces/RecordEntities';
import { ListItemProps } from '../../interfaces/PagesProps';
type IProps = ListItemProps<Article>;
export const ArticleListItem: React.FC<IProps> = ({ record }) => {
return (
<div>
<div className="title">{record.title}</div>
<div className="author">By {record.author?.name || 'Unknown'}</div>
</div>
);
};
yarn start
git add .
git commit -m "Fetching"