Skip to content

Commit fc18bb9

Browse files
authored
Merge pull request #7 from the-road-to-learn-react/hooks-improvements
Hooks Data Fetching Improvements
2 parents e7c4cfa + 2a7516f commit fc18bb9

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

src/useDataApiHook-example/index.js

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,75 @@
1-
import React, { Fragment, useState, useEffect } from 'react';
1+
import React, {
2+
Fragment,
3+
useState,
4+
useEffect,
5+
useReducer,
6+
} from 'react';
27
import axios from 'axios';
38

9+
function dataFetchReducer(state, action) {
10+
switch (action.type) {
11+
case 'FETCH_INIT':
12+
return { ...state, isLoading: true, isError: false };
13+
case 'FETCH_SUCCESS':
14+
return {
15+
...state,
16+
isLoading: false,
17+
isError: false,
18+
data: action.payload,
19+
};
20+
case 'FETCH_FAILURE':
21+
return {
22+
...state,
23+
isLoading: false,
24+
isError: true,
25+
data: { hits: [] },
26+
};
27+
default:
28+
throw new Error();
29+
}
30+
}
31+
432
const useDataApi = (initialUrl, initialData) => {
5-
const [data, setData] = useState(initialData);
633
const [url, setUrl] = useState(initialUrl);
7-
const [isLoading, setIsLoading] = useState(false);
8-
const [isError, setIsError] = useState(false);
934

10-
const fetchData = async () => {
11-
setIsError(false);
12-
setIsLoading(true);
35+
const [state, dispatch] = useReducer(dataFetchReducer, {
36+
isLoading: false,
37+
isError: false,
38+
data: initialData,
39+
});
1340

14-
try {
15-
const result = await axios(url);
41+
useEffect(() => {
42+
let didCancel = false;
1643

17-
setData(result.data);
18-
} catch (error) {
19-
setIsError(true);
20-
}
44+
const fetchData = async () => {
45+
dispatch({ type: 'FETCH_INIT' });
2146

22-
setIsLoading(false);
23-
};
47+
try {
48+
const result = await axios(url);
49+
50+
if (!didCancel) {
51+
dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
52+
}
53+
} catch (error) {
54+
if (!didCancel) {
55+
dispatch({ type: 'FETCH_FAILURE' });
56+
}
57+
}
58+
};
2459

25-
useEffect(() => {
2660
fetchData();
61+
62+
return () => {
63+
didCancel = true;
64+
};
2765
}, [url]);
2866

2967
const doGet = (event, url) => {
3068
setUrl(url);
3169
event.preventDefault();
3270
};
3371

34-
return { data, isLoading, isError, doGet };
72+
return { ...state, doGet };
3573
};
3674

3775
function App() {

0 commit comments

Comments
 (0)