|
1 | | -import React from "react"; |
| 1 | +import React, {useState, useReducer, useContext, createContext} from "react"; |
| 2 | +import produce from "immer"; |
2 | 3 |
|
3 | | -import {useAxiosGet} from "../../../src"; |
| 4 | +import {useAxiosGet, useAxiosPost, useAxios} from "../../../src"; |
4 | 5 |
|
5 | 6 |
|
| 7 | +const Context = createContext(); |
| 8 | + |
6 | 9 | function ListPosts() { |
7 | | - const {status, response} = useAxiosGet({ |
8 | | - url: "http://localhost:3001/posts" |
| 10 | + const {state, dispatch} = useContext(Context); |
| 11 | + const [postId, setPostId] = useState(null); |
| 12 | + const {status} = useAxiosGet({ |
| 13 | + url: "http://localhost:3001/posts", |
| 14 | + successCb: response => { |
| 15 | + dispatch({type: "FETCHED_POSTS", payload: response}); |
| 16 | + } |
| 17 | + }); |
| 18 | + const {dispatchFetch} = useAxios({ |
| 19 | + url: `http://localhost:3001/posts/${postId}`, |
| 20 | + method: "DELETE", |
| 21 | + controlledFetch: true |
9 | 22 | }); |
10 | 23 | if (status === "loading") { |
11 | 24 | return <h5>Loading posts...</h5>; |
12 | 25 | } |
13 | 26 | else if (status === "error") { |
14 | | - return <h5>Error in loading posts.</h5>; |
| 27 | + return <h5 style={{color: "red"}}>Error in loading posts</h5>; |
15 | 28 | } |
16 | | - else if (status === "success") { |
17 | | - return ( |
18 | | - <ul> |
19 | | - {" "} |
20 | | - {response.map(item => ( |
21 | | - <li key={item.id}> |
22 | | - {item.title}, {item.author} |
23 | | - </li> |
24 | | - ))}{" "} |
25 | | - </ul> |
26 | | - ); |
| 29 | + |
| 30 | + function handleDeletePost(post) { |
| 31 | + setPostId(post.id); |
| 32 | + dispatchFetch(); |
| 33 | + dispatch({type: "DELETED_POST", id: post.id}); |
27 | 34 | } |
28 | | - else { |
29 | | - return null; |
| 35 | + |
| 36 | + return ( |
| 37 | + <ul> |
| 38 | + {state.posts.map(post => ( |
| 39 | + <li key={post.id}> |
| 40 | + {post.title} by <strong>{post.author}</strong>{" "} |
| 41 | + <a href="javascript:void(0)" onClick={() => handleDeletePost(post)}> |
| 42 | + Delete Post |
| 43 | + </a> |
| 44 | + </li> |
| 45 | + ))} |
| 46 | + </ul> |
| 47 | + ); |
| 48 | +} |
| 49 | + |
| 50 | +function AddPost() { |
| 51 | + const {dispatch} = useContext(Context); |
| 52 | + const [title, setTitle] = useState(""); |
| 53 | + const [author, setAuthor] = useState(""); |
| 54 | + const {dispatchFetch, status} = useAxiosPost({ |
| 55 | + url: "http://localhost:3001/posts", |
| 56 | + controlledFetch: true, |
| 57 | + options: { |
| 58 | + data: { |
| 59 | + title: title, |
| 60 | + author: author |
| 61 | + } |
| 62 | + }, |
| 63 | + successCb: response => { |
| 64 | + dispatch({type: "ADD_POST", payload: response}); |
| 65 | + } |
| 66 | + }); |
| 67 | + |
| 68 | + const loading = status === "loading"; |
| 69 | + return ( |
| 70 | + <div> |
| 71 | + <input value={title} onChange={e => setTitle(e.target.value)} disabled={loading}/> |
| 72 | + <input value={author} onChange={e => setAuthor(e.target.value)} disabled={loading}/> |
| 73 | + <button onClick={() => dispatchFetch()} disabled={loading}> |
| 74 | + {loading ? "Loading..." : "Add Post"} |
| 75 | + </button> |
| 76 | + </div> |
| 77 | + ); |
| 78 | +} |
| 79 | + |
| 80 | +const initState = {posts: []}; |
| 81 | + |
| 82 | +function reducer(state, action) { |
| 83 | + switch (action.type) { |
| 84 | + case "ADD_POST": |
| 85 | + return produce(state, draftState => { |
| 86 | + draftState.posts.push(action.payload); |
| 87 | + }); |
| 88 | + case "FETCHED_POSTS": |
| 89 | + return produce(state, draftState => { |
| 90 | + draftState.posts = action.payload; |
| 91 | + }); |
| 92 | + case "DELETED_POST": |
| 93 | + return produce(state, draftState => { |
| 94 | + const {posts} = state, |
| 95 | + index = posts.findIndex(post => post["id"] === action.id); |
| 96 | + draftState.posts.splice(index, 1); |
| 97 | + }); |
| 98 | + default: |
| 99 | + return state; |
30 | 100 | } |
31 | 101 | } |
32 | 102 |
|
33 | 103 | export default function AxiosAPIExample(props) { |
| 104 | + const [state, dispatch] = useReducer(reducer, initState); |
34 | 105 | return ( |
35 | | - <div> |
| 106 | + <Context.Provider value={{state, dispatch}}> |
36 | 107 | <ListPosts/> |
37 | | - </div> |
| 108 | + <AddPost/> |
| 109 | + </Context.Provider> |
38 | 110 | ); |
39 | 111 | } |
0 commit comments