【问题标题】:Toggle Elements during onClick在 onClick 期间切换元素
【发布时间】:2021-09-12 15:36:44
【问题描述】:

基本上我有一个通过递归嵌套的 cmets。

目前这是组件的行为

点击前:

点击后:

当我点击按钮时如何切换组件?

附上我的代码

//data.js

const post = {
    "post": {
        "img": "",
        "likes": [
            "60c418582f7066090ced4a51"
        ],
        "comments": [
            {
                "comments": [
                    {
                        "comments": [
                            {
                                "comments": [
                                    {
                                        "comments": [],
                                        "_id": "60d6ab9207c0a573786a9e65",
                                        "userId": "60c418582f7066090ced4a51",
                                        "content": "good post 3",
                                        "createdAt": "2021-06-26T04:22:42.337Z",
                                        "updatedAt": "2021-06-26T04:22:42.337Z",
                                        "__v": 0
                                    }
                                ],
                                "_id": "60d6962cee10aa73f820b974",
                                "userId": "60c418582f7066090ced4a51",
                                "content": "good post 2",
                                "createdAt": "2021-06-26T02:51:24.111Z",
                                "updatedAt": "2021-06-26T04:22:42.622Z",
                                "__v": 0
                            },
                            {
                                "comments": [],
                                "_id": "60d705784ab01c354cf7f445",
                                "userId": "60c15ac41ed8da1ab4efe7f3",
                                "content": "Comment deleted by User",
                                "createdAt": "2021-06-26T10:46:16.813Z",
                                "updatedAt": "2021-06-26T12:29:06.398Z",
                                "__v": 0
                            },
                            {
                                "comments": [],
                                "_id": "60d706febcba957b04406547",
                                "userId": "60c15ac41ed8da1ab4efe7f3",
                                "content": "yes it is a good post 1 from alexane Updated",
                                "createdAt": "2021-06-26T10:52:46.679Z",
                                "updatedAt": "2021-06-26T12:17:58.879Z",
                                "__v": 0
                            }
                        ],
                        "_id": "60d695b4ee10aa73f820b973",
                        "userId": "60c418582f7066090ced4a51",
                        "content": "good post 1",
                        "createdAt": "2021-06-26T02:49:24.426Z",
                        "updatedAt": "2021-06-26T12:30:44.872Z",
                        "__v": 0
                    }
                ],
                "_id": "60d68e32dff84439a4d3b191",
                "userId": "60c418582f7066090ced4a51",
                "content": "good post",
                "createdAt": "2021-06-26T02:17:22.625Z",
                "updatedAt": "2021-06-26T02:49:24.820Z",
                "__v": 0
            },
            {
                "comments": [
                    {
                        "comments": [],
                        "_id": "60d6c2d917d0b12be44742d2",
                        "userId": "60c418582f7066090ced4a51",
                        "content": "nice post 1",
                        "createdAt": "2021-06-26T06:02:01.420Z",
                        "updatedAt": "2021-06-26T06:02:01.420Z",
                        "__v": 0
                    }
                ],
                "_id": "60d6bebf17d0b12be44742d1",
                "userId": "60c418582f7066090ced4a51",
                "content": "nice post",
                "createdAt": "2021-06-26T05:44:31.436Z",
                "updatedAt": "2021-06-26T06:02:01.676Z",
                "__v": 0
            },
            {
                "comments": [
                    {
                        "comments": [],
                        "_id": "60d87e7df43fed7e4079875e",
                        "userId": "60c15ac41ed8da1ab4efe7f3",
                        "content": "awesome post 1",
                        "createdAt": "2021-06-27T13:34:53.192Z",
                        "updatedAt": "2021-06-27T13:34:53.192Z",
                        "__v": 0
                    }
                ],
                "_id": "60d87cb4f43fed7e4079875d",
                "userId": "60c418582f7066090ced4a51",
                "content": "awesome post",
                "createdAt": "2021-06-27T13:27:16.299Z",
                "updatedAt": "2021-06-27T13:34:53.468Z",
                "__v": 0
            }
        ],
        "_id": "60c5a23eb37b425a00968fa9",
        "userId": "60c418582f7066090ced4a51",
        "description": "This is a sample Post 2",
        "createdAt": "2021-06-13T06:14:22.196Z",
        "updatedAt": "2021-06-27T13:27:16.577Z",
        "__v": 0
    },
    "count": 10
}
export default post
    


 //Comment.js
import post from './data'
const NestedComments = () => {
    const [comments, setComments] = useState(post.post.comments);

    return (<div className="commentDiv">
        <div>
            <span>Username</span>
        </div>
        <Comments
            comments={comments}
        />
    </div>)
}

const Comments = ({
    comments,
}) => {
    const [isClicked, setisClicked] = useState(false);
    const [commentId, setcommentId] = useState(null);

    const nestedComments = (comment) => {
        return comment.comments ? (
            <div className={`childCommentsof-${comment._id}`}>
                <Comments
                    comments={comment.comments}
                />
            </div>
        ) : null
    }

    const trigger = (e, id) => {
        e.preventDefault()
        if (e.target.className.baseVal === 'MuiSvgIcon-root') {
            const targetId = e.target.parentElement.id
            if (targetId === id) {
                setisClicked(!isClicked)
                setcommentId(id)
            }
            return
        }
    }



    return (
        <>
            {
                (comments || []).map(comment => {
                    return (
                        <ul key={comment._id} className={`commentsUL-${comment._id} commentsList`} >
                            <li>
                                <button className='customBtn' id={comment._id}>
                                    {
                                        (!isClicked || comment._id !== commentId) && <Remove onClick={(e) => trigger(e, comment._id)} />
                                    }
                                    {
                                        isClicked === true && comment._id === commentId && <Add />
                                    }
                                </button>

                                {comment.content}
                                <span><button>Reply</button></span>
                            </li>
                            {nestedComments(comment)}
                        </ul>
                    )
                })
            }
        </>
    )
}

目前的行为是当用户点击减号按钮时,只有一个按钮会切换并变成加号按钮。我想要实现的是当用户点击减号按钮时,它会变成加号? javascript 方式将使用 e.target 并替换元素。

如何使用 React 来实现?我有点卡在这里几个小时,任何帮助将不胜感激。谢谢。

我们将不胜感激。谢谢。

【问题讨论】:

    标签: javascript reactjs recursion


    【解决方案1】:

    好的,你需要做的是在你的组件中维护一个被点击的 cmets 列表。

    const [clickedCommentIdList, setClickedCommentIdList] = useState([]);
    

    现在当您触发时,您需要像这样更新列表

    setClickedCommentIdList((prev) => [...prev, id]);
    

    最后在你的组件内部检查组件是否已经被检查

    {!checkIfClicked(comment._id) ? (
                      <button onClick={(e) => trigger(e, comment._id)}>
                        remove
                      </button>
                    ) : (
                      <button>Add</button>
                    )}
    

    这是你的工作版本

    https://codesandbox.io/s/happy-snow-dqbbc?file=/src/App.js:5031-5267

    【讨论】:

    • 非常感谢。沙盒对我真的很有帮助。一百万谢谢:)
    • 乐于助人:D
    【解决方案2】:

    您可以通过创建具有自己状态的单个评论组件来简化 trigger 函数的逻辑(或将其完全删除)。这使得它变得更加简单,因为您不需要检查 id 或任何东西。

    如果您需要添加额外的类,您可以通过检查 isClicked 内部的 &lt;SingleComment /&gt; 来完成。

    这是最终的代码——我进行了一些重构以使其更易于维护/阅读:

    import React, { useState } from "react";
    import post from "./data";
    
    // Single comment
    const SingleComment = ({ comment }) => {
      const [isClicked, setIsClicked] = useState(false);
    
      return (
        <li>
          <button className="customBtn" id={comment._id}>
            {!isClicked && (
              <Remove
                onClick={(e) => {
                  setIsClicked(!isClicked);
                  // add your remove comment logic here
                }}
              />
            )}
            {isClicked && <Add />}
          </button>
    
          {comment.content}
          <span>
            <button>Reply</button>
          </span>
        </li>
      );
    };
    
    // Nested comments
    const NestedComments = () => {
      const [comments, setComments] = useState(post.post.comments);
    
      return (
        <div className="commentDiv">
          <div>
            <span>Username</span>
          </div>
          <Comments comments={comments} />
        </div>
      );
    };
    
    // Comment list
    const Comments = ({ comments }) => (
      <>
        {(comments || []).map((comment) => (
          <ul
            key={comment._id}
            className={`commentsUL-${comment._id} commentsList`}
          >
            <SingleComment comment={comment} />
            {comment.comments && <NestedComments />}
          </ul>
        ))}
      </>
    );
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-09
      • 1970-01-01
      • 2020-02-19
      • 2014-03-13
      • 1970-01-01
      • 2019-10-17
      • 2018-05-18
      • 2020-11-16
      相关资源
      最近更新 更多