简体   繁体   English

在 API 调用后反应重新渲染

[英]React re-render after API call

I'm working on a simple React app alongside TypeScript, and I'm using JSONPlaceholder for API calls simulation.我正在与 TypeScript 一起开发一个简单的 React 应用程序,并且我正在使用 JSONPlaceholder 进行 API 调用模拟。 I have implemented everything I need, but facing a problem when it comes to re-rendering components that shows response data from API.我已经实现了我需要的一切,但是在重新渲染显示来自 API 的响应数据的组件时遇到了问题。 The thing is that if I do HTTP GET to all data after I do DELETE or PUT, I will again get all same data because data changes don't actually apply on the server.问题是,如果我在执行 DELETE 或 PUT 之后对所有数据执行 HTTP GET,我将再次获得所有相同的数据,因为数据更改实际上并不适用于服务器。 I will appreciate it if you can help me how to edit my functions for DELETE and PUT.如果您能帮助我编辑 DELETE 和 PUT 函数,我将不胜感激。

When I console.log my responses inside components, I get staus ok 200, so the API call part is fine, the only thing that I struggle with is how to re-render components properly当我 console.log 我在组件中的响应时,我得到了状态 ok 200,所以 API 调用部分很好,我唯一遇到的问题是如何正确地重新渲染组件

There is a component that shows all data, and also make calls to DELETE endpoint, and shows modal where I call PUT endpoint:有一个组件可以显示所有数据,还可以调用 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;

And also, there is a modal component with PUT function:此外,还有一个带有 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;

And at the end, my PostService.ts and HTTP files where is axios code to call API points:最后,我的 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',
  },
});

Thank you all guys:)谢谢大家:)

Your delete function uses "setPosts(posts)" which I'm pretty sure is not what you meant.您的删除 function 使用“setPosts(posts)”,我很确定这不是您的意思。 Also, your modal does not tell your main component that a post has been edited, I guess that's the problem?另外,您的模态不会告诉您的主要组件帖子已被编辑,我想这就是问题所在? Pass a callback to the modal to update the posts state in the main component.将回调传递给模态以更新主组件中的帖子 state。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 登录后和异步调用后,React重新渲染 - React re-render after login — and after an asynchronous call post请求api反应后重新渲染组件 - re-render component after post request api react CoinGecko API 数据在重新渲染 React JS 后未定义 - CoinGecko API data undefined after re-render React JS API 没有调用第一次渲染,只有在我手动重新渲染 React 应用程序之后 - API is not calling on first render, only after I manually re-render React app React 避免在重新渲染后重新调用函数 - React avoid re-calling functions after re-render 祖父母回调中的反应组件在孙子调用后不会重新呈现页面 - React component of grandparent callback doesnt re-render page after being call in grandchild 在事件处理程序中进行 setState 调用后,React 何时重新渲染 - When does React re-render after a setState call made inside an event handler 流星反应:如何在Meteor.call回调完成后在setState内的状态上重新渲染? - Meteor-React: How to re-render on a state inside setState after Meteor.call callback finishes? React Context api - 消费者在上下文更改后不重新呈现 - React Context api - Consumer Does Not re-render after context changed react-google-maps/api 避免在某些状态更改后重新渲染 Map - react-google-maps/api Avoiding re-render of Map after some state changes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM