簡體   English   中英

在 API 調用后反應重新渲染

[英]React re-render after API call

我正在與 TypeScript 一起開發一個簡單的 React 應用程序,並且我正在使用 JSONPlaceholder 進行 API 調用模擬。 我已經實現了我需要的一切,但是在重新渲染顯示來自 API 的響應數據的組件時遇到了問題。 問題是,如果我在執行 DELETE 或 PUT 之后對所有數據執行 HTTP GET,我將再次獲得所有相同的數據,因為數據更改實際上並不適用於服務器。 如果您能幫助我編輯 DELETE 和 PUT 函數,我將不勝感激。

當我 console.log 我在組件中的響應時,我得到了狀態 ok 200,所以 API 調用部分很好,我唯一遇到的問題是如何正確地重新渲染組件

有一個組件可以顯示所有數據,還可以調用 DELETE 端點,並在我調用 PUT 端點的地方顯示模式:

const PostsTable: React.FunctionComponent = () => {
  const [posts, setPosts] = useState<Array<IPost>>([]);
  const [selectedPost, setSelectedPost] = useState<IPost>({});
  const [dialogOpen, setDialogOpen] = useState<boolean>(false);

  const fetchPosts = () => {
    PostService.getAllPosts()
      .then((response: any) => {
        setPosts(response.data);
      })
      .catch((e: Error) => {
        console.log(e);
      });
  };

  useEffect(() => {
    fetchPosts();
  }, []);

  const editPost = (post: IPost) => (event: any) => {
    setSelectedPost(post);
    setDialogOpen(true);
  };

  const handleClose = () => {
    setDialogOpen(false);
  };

  const deletePost =
    (id: any): any =>
    (event: Event) => {
      event.stopPropagation();
      PostService.deletePost(id)
        .then((response: any) => {
          setPosts(posts);
          console.log(response);
        })
        .catch((e: Error) => {
          console.log(e);
        });
    };

  return (
    <Container fixed>
      {!posts || posts.length < 1 ? (
        <div style={{ display: 'flex', justifyContent: 'center' }}>
          <CircularProgress color="primary" size={100} />
        </div>
      ) : (
        <TableContainer component={Paper}>
          <Table sx={{ minWidth: 650 }} aria-label="simple table">
            <TableHead>
              <TableRow>
                <TableCell align="left">User Id</TableCell>
                <TableCell align="left">Post Id</TableCell>
                <TableCell align="left">Title</TableCell>
                <TableCell align="left">Actions</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {posts.map((post: IPost) => (
                <TableRow
                  key={post.id}
                  sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
                >
                  <TableCell>{post.userId}</TableCell>
                  <TableCell align="left">{post.id}</TableCell>
                  <TableCell align="left">{post.title}</TableCell>
                  <TableCell align="left">
                    <Tooltip title="Delete">
                      <IconButton onClick={editPost(post)}>
                        <EditIcon />
                      </IconButton>
                    </Tooltip>
                    <Tooltip title="Edit">
                      <IconButton onClick={deletePost(post.id)}>
                        <DeleteIcon />
                      </IconButton>
                    </Tooltip>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </TableContainer>
      )}
      {
        <EditPostDialog
          open={dialogOpen}
          handleClose={handleClose}
          selectedPost={selectedPost}
        />
      }
    </Container>
  );
};

export default PostsTable;

此外,還有一個帶有 PUT function 的模態組件:

const EditPostDialog: React.FunctionComponent<IEditPostDialog> = (
  props: IEditPostDialog
) => {
  const { open, handleClose, selectedPost } = props;

  const [post, setPost] = useState<IPost>({});

  useEffect(() => {
    const newPost = {
      id: selectedPost.id,
      userId: selectedPost.userId,
      title: selectedPost.title,
      body: selectedPost.body,
    };
    setPost(newPost);
  }, [selectedPost]);

  const handleChange = (event: any) => {
    setPost({ ...post, [event.target.name]: event.target.value });
  };

  const handleSubmit = () => {
    PostService.updatePost(post.id, post)
      .then((response: any) => {
        console.log(response);
      })
      .catch((e: Error) => {
        console.log(e);
      });
    handleClose();
  };

  return (
    <Dialog onClose={handleClose} open={open}>
      <DialogTitle id="simple-dialog-title">Post info</DialogTitle>
      <DialogContent classes={{ root: 'dialog-content' }}>
        <TextField
          id="userId"
          label="User Id"
          name="userId"
          variant="outlined"
          value={post.userId}
          onChange={handleChange}
          style={{ marginTop: 16 }}
        />
        <TextField
          id="title"
          label="Title"
          name="title"
          variant="outlined"
          value={post.title}
          onChange={handleChange}
        />
        <TextField
          id="body"
          label="Body"
          name="body"
          variant="outlined"
          value={post.body}
          onChange={handleChange}
          multiline
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose}>Close</Button>
        <Button onClick={handleSubmit}>Submit</Button>
      </DialogActions>
    </Dialog>
  );
};

export default EditPostDialog;

最后,我的 PostService.ts 和 HTTP 文件在哪里是 axios 代碼來調用 API 點:

const getAllPosts = () => {
  return http.get<Array<IPost>>('/posts');
};

const getSinglePost = (id: number | undefined) => {
  return http.get<IPost>(`/posts/${id}`);
};

const createPost = (data: IPost) => {
  return http.post<IPost>('/posts', data);
};

const updatePost = (id: number | undefined, data: IPost) => {
  return http.put<any>(`/posts/${id}`, data);
};

const deletePost = (id: number | undefined) => {
  return http.delete<any>(`/posts/${id}`);
};

const PostService = {
  getAllPosts,
  getSinglePost,
  createPost,
  updatePost,
  deletePost,
};
export default axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com',
  headers: {
    'Content-type': 'application/json',
  },
});

謝謝大家:)

您的刪除 function 使用“setPosts(posts)”,我很確定這不是您的意思。 另外,您的模態不會告訴您的主要組件帖子已被編輯,我想這就是問題所在? 將回調傳遞給模態以更新主組件中的帖子 state。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM