【问题标题】:React re-render after API callAPI调用后反应重新渲染
【发布时间】:2022-01-25 21:36:48
【问题描述】:

我正在与 TypeScript 一起开发一个简单的 React 应用程序,并且我正在使用 JSONPlaceholder 进行 API 调用模拟。我已经实现了我需要的一切,但是在重新渲染显示来自 API 的响应数据的组件时遇到了问题。问题是,如果我在执行 DELETE 或 PUT 之后对所有数据执行 HTTP GET,我将再次获得所有相同的数据,因为数据更改实际上并不适用于服务器。 如果您能帮助我编辑 DELETE 和 PUT 函数,我将不胜感激。

当我 console.log 我在组件中的响应时,我得到 staus 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 功能的模态组件:

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 文件在哪里是调用 API 点的 axios 代码:

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',
  },
});

谢谢大家:)

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    您的删除功能使用“setPosts(posts)”,我很确定这不是您的意思。此外,您的模态不会告诉您的主要组件帖子已被编辑,我想这就是问题所在?将回调传递给 modal 以更新主组件中的帖子状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 2016-07-13
      • 2022-01-04
      • 2019-12-13
      相关资源
      最近更新 更多