-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseSearch.js
More file actions
85 lines (73 loc) · 2.2 KB
/
useSearch.js
File metadata and controls
85 lines (73 loc) · 2.2 KB
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
import React, { useMemo, useReducer, useContext } from 'react';
const SearchContext = React.createContext();
function searchReducer(state, action) {
switch (action.type) {
case 'FETCH_START':
return {
...state,
isLoading: true,
error: null
};
case 'FETCH_SUCCESS':
return {
isLoading: false,
error: null,
data: action.data
};
case 'FETCH_ERROR':
return {
...state,
isLoading: false,
error: action.error
};
default:
return state;
}
}
function SearchContextProvider(props) {
const [state, dispatch] = useReducer(searchReducer, {
isLoading: false,
error: null,
data: null
});
const actions = useMemo(
() => ({
search: (query, page = 1) => {
dispatch({ type: 'FETCH_START' });
const handleResolve = data => {
dispatch({ type: 'FETCH_SUCCESS', data });
};
const handleReject = () => {
dispatch({
type: 'FETCH_FAILURE',
error: 'Could not obtain the data'
});
};
const handleError = error => {
dispatch({ type: 'FETCH_FAILURE', error });
};
fetch(
`https://reactworkshop-api.herokuapp.com/3/search/multi?query=${query}&page=${page}`
)
.then(response => response.json())
.then(handleResolve, handleReject)
.catch(handleError);
}
}),
[]
);
const context = useMemo(
() => ({
...state,
actions
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[state]
);
return <SearchContext.Provider value={context} {...props} />;
}
function useSearch() {
return useContext(SearchContext);
}
export default useSearch;
export { useSearch, SearchContext, SearchContextProvider };