首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获得分配给delete函数的正确ID?

如何获得分配给delete函数的正确ID?
EN

Stack Overflow用户
提问于 2021-06-04 20:09:49
回答 3查看 75关注 0票数 2

我正在学习,同时创建一个测试应用程序,可以让你创建一个表单的帖子。我已经卡在删除功能上已经五天了。

我能够正确地映射帖子,将post_body打印到每一张卡上,但是当尝试删除时,它总是删除数据库中的最后一项。

我的猜测是,这与道具有关,我花了几天时间尝试不同的方法,通过一个功能组件传递道具,但没有运气。

如屏幕截图所示,在返回时,我为每一张卡片打印了post_id,这样您就可以看到为每一张卡指定了正确的ID。但是,一旦您进入popover组件,post_ID似乎总是使用最底层post的值。

任何方向都是感激的。

(注意:我确信这段代码相当草率,我可能不应该在这么大的代码块上映射。一旦我弄清楚这些道具应该如何工作,我可能会尝试重构)

代码语言:javascript
复制
const ListPosts = (props) => {

  const [posts, setPosts] = useState([]);

  // Delete Post
  const deletePost = async id => {
    try {
        const deletePost = await fetch(`http://localhost:3000/posts/${id}`, {
          method: "DELETE"
      });
  
      setPosts(posts.filter(post => post.post_id !== id));  
      console.log(deletePost);
    } catch (err) {
      console.error(err.message);
    }
  }

  // Options Popover
  const [show, setShow] = useState(false);
  const [target, setTarget] = useState(null);
  const ref = useRef(null);

  const handleClick = (event) => {
    setShow(!show);
    setTarget(event.target);
  }
  

  // Get Posts Function
  const getPosts = async() => {
    try {
      
      const response = await fetch("http://localhost:3000/posts")
      const jsonData = await response.json()

      setPosts(jsonData);

    } catch (err) {
      console.error(err.message)
    }
  };

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

  console.log(posts);


  return (
    <Fragment>
      {/* Map Post Text */}
      {posts.map(post => (
      <Card className="post-card" style={{ marginTop: "15px" }} key={post.post_id}> 
        <Card.Body>
          <div className="post-container">
            <div className="post-header row">
              <div className="user-photo-icon col-1"></div>
              <div className="user-names col-9"></div>
              <div className="options-menu col-2 ">
                <div ref={ref}>
                  <Button className="options-btn-popover" onClick={handleClick}>
                    <FontAwesomeIcon icon={ faEllipsisH } color="#848484" size="1x" className="options-icon" />
                  </Button>
                  
                  {/* Placed to show the point at which the ID's are still correct */}
                  {post.post_id}

                  <Overlay
                    show={show}
                    target={target}
                    placement="left"
                    container={ref.current}
                  >
                    <Popover className="shadow-sm" id="popover-contained" >

                      {/* Placed to show that now all id's show the post_id of the last post */}
                      {post.post_id}

                      <Popover.Content>
                        <div className="mb-2">
                          <Button className="options-btn-popover">
                            <FontAwesomeIcon icon={ faPencilAlt } size="1x" className="post-options-icon"/> 
                            Edit Post
                          </Button>
                        </div>
                        <div>
                          <Button className="options-btn-popover" onClick={() => deletePost(post.post_id)}>
                          <FontAwesomeIcon icon={ faTrashAlt } color="" size="1x" className="post-options-icon" /> 
                            Delete Post
                          </Button>
                        </div>
                      </Popover.Content>
                    </Popover>  
                  </Overlay>
                </div>
              </div>
            </div>
            <div className="post-text">{post.post_body}</div>
            <div className="post-media"></div>
            <div className="post-actions"></div>
            <div className="post-comments">
              <div className="post-subcomments"></div>
            </div>
          </div>
        </Card.Body>  
      </Card>
      ))}
    </Fragment>
  )
};

这是一张截图:

贴有邮政身份证的邮件列表

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-06-04 20:51:13

问题

我怀疑这是因为您只有一个show状态,当切换时打开,所有的,弹出框。所有的弹出式都是打开的,但它们都是相对于target元素的位置,它们都是重叠的,最后一个是在顶部。

解决方案

我建议将当前的post id存储在“显示”状态中,并有条件地检查/匹配以打开特定的弹出。

  1. null初始状态开始: setShow = useState(null);
  2. 更新单击处理程序以使用post id并对事件对象进行咖喱。将show状态设置为当前单击的post id。 handleClick = (postId) => (事件) => { setShow(postId);setTarget(event.target);}
  3. 映射按钮时传递post.post_id
  4. 映射覆盖/弹出时检查当前的post id。如果当前post id与存储在show状态中的内容匹配,则计算true,否则为false。 .
  5. 删除操作完成后,清除show状态。函数状态更新以正确地从以前的状态(而不是从回调触发的呈现周期中的状态)进行更新。 deletePost =异步=> {http://localhost:3000/posts/${id},{方法:“删除”};setPosts(post => posts.filter(post => post.post_id !== id));// <-函数更新console.log( deletePost );} catch (err) { console.error(err.message);}最后{ setShow( null );// <- reset to null}
票数 2
EN

Stack Overflow用户

发布于 2021-06-04 20:50:20

你能试着用竞逐来完成这个任务吗?

下面是我做的一个小改动的代码。当我们声明deletePost时,您会注意到它将id作为param,然后调用另一个函数。然后,当您调用这个delete函数时,您不再需要在=>之前使用() deletePost。

TLDR: currying允许您在执行时间之前传入值。

代码语言:javascript
复制
const ListPosts = (props) => {

  const [posts, setPosts] = useState([]);

  // Delete Post
  const deletePost = id => async => {
    try {
        const deletePost = await fetch(`http://localhost:3000/posts/${id}`, {
          method: "DELETE"
      });
  
      setPosts(posts.filter(post => post.post_id !== id));  
      console.log(deletePost);
    } catch (err) {
      console.error(err.message);
    }
  }

  // Options Popover
  const [show, setShow] = useState(false);
  const [target, setTarget] = useState(null);
  const ref = useRef(null);

  const handleClick = (event) => {
    setShow(!show);
    setTarget(event.target);
  }
  

  // Get Posts Function
  const getPosts = async() => {
    try {
      
      const response = await fetch("http://localhost:3000/posts")
      const jsonData = await response.json()

      setPosts(jsonData);

    } catch (err) {
      console.error(err.message)
    }
  };

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

  console.log(posts);


  return (
    <Fragment>
      {/* Map Post Text */}
      {posts.map(post => (
      <Card className="post-card" style={{ marginTop: "15px" }} key={post.post_id}> 
        <Card.Body>
          <div className="post-container">
            <div className="post-header row">
              <div className="user-photo-icon col-1"></div>
              <div className="user-names col-9"></div>
              <div className="options-menu col-2 ">
                <div ref={ref}>
                  <Button className="options-btn-popover" onClick={handleClick}>
                    <FontAwesomeIcon icon={ faEllipsisH } color="#848484" size="1x" className="options-icon" />
                  </Button>
                  
                  {/* Placed to show the point at which the ID's are still correct */}
                  {post.post_id}

                  <Overlay
                    show={show}
                    target={target}
                    placement="left"
                    container={ref.current}
                  >
                    <Popover className="shadow-sm" id="popover-contained" >

                      {/* Placed to show that now all id's show the post_id of the last post */}
                      {post.post_id}

                      <Popover.Content>
                        <div className="mb-2">
                          <Button className="options-btn-popover">
                            <FontAwesomeIcon icon={ faPencilAlt } size="1x" className="post-options-icon"/> 
                            Edit Post
                          </Button>
                        </div>
                        <div>
                          <Button className="options-btn-popover" onClick={deletePost(post.post_id)}>
                          <FontAwesomeIcon icon={ faTrashAlt } color="" size="1x" className="post-options-icon" /> 
                            Delete Post
                          </Button>
                        </div>
                      </Popover.Content>
                    </Popover>  
                  </Overlay>
                </div>
              </div>
            </div>
            <div className="post-text">{post.post_body}</div>
            <div className="post-media"></div>
            <div className="post-actions"></div>
            <div className="post-comments">
              <div className="post-subcomments"></div>
            </div>
          </div>
        </Card.Body>  
      </Card>
      ))}
    </Fragment>
  )
};
票数 1
EN

Stack Overflow用户

发布于 2021-06-04 20:52:18

我认为问题在于您要在循环内部创建Overlay/Popover组件,尝试将其移出循环。然后,您可以使用const [selectedPost, selectPost] = useState()来跟踪应该在覆盖层中呈现的数据。按钮被点击了。还调整onClick={handleClick}以调用selectPost(post)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67843424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档