-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathindex.js
102 lines (86 loc) · 2.11 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import React, { Fragment, useState, useEffect, useReducer } from 'react';
import axios from 'axios';
const dataFetchReducer = (state, action) => {
switch (action.type) {
case 'FETCH_INIT':
return { ...state, isLoading: true, isError: false };
case 'FETCH_SUCCESS':
return {
...state,
isLoading: false,
isError: false,
data: action.payload
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true
};
default:
throw new Error();
}
};
const useDataApi = (initialData, initialUrl = 'http://hn.algolia.com/api/v1/search?query=redux') => {
const [ url, setUrl ] = useState(initialUrl);
const [ state, dispatch ] = useReducer(dataFetchReducer, {
// passing isLoading and isError property is redundant here
data: initialData
});
useEffect(
() => {
let didCancel = false;
const fetchData = async () => {
dispatch({ type: 'FETCH_INIT' });
try {
const result = await axios(url);
if (!didCancel) {
dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
}
} catch (error) {
if (!didCancel) {
dispatch({ type: 'FETCH_FAILURE' });
}
}
};
fetchData();
return () => {
didCancel = true;
};
},
[ url ]
);
return [ state, setUrl ];
};
function App() {
const [ query, setQuery ] = useState('redux');
// Now our Custom hookAPI resemble more like native hook
const [ result, setUrl ] = useDataApi({ hits: [] });
const { data, isLoading, isError } = result;
return (
<Fragment>
<form
onSubmit={(event) => {
setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`);
event.preventDefault();
}}
>
<input type="text" value={query} onChange={(event) => setQuery(event.target.value)} />
<button type="submit">Search</button>
</form>
{isError && <div style={{ color: 'red' }}>Something went wrong ...</div>}
{isLoading ? (
<div>Loading ...</div>
) : (
<ul>
{data.hits.map((item) => (
<li key={item.objectID}>
<a href={item.url}>{item.title}</a>
</li>
))}
</ul>
)}
</Fragment>
);
}
export default App;