【问题标题】:How do you remove a CSS class from a certain element of a list with React如何使用 React 从列表的某个元素中删除 CSS 类
【发布时间】:2021-10-31 10:49:14
【问题描述】:

我试图在单击该项目的按钮时从特定项目中删除 CSS 类。删除 CSS 类会出现一个菜单。我将如何使用 React 来做这件事?这是代码。

import "./Homepage.css"
import React, { useState, useEffect, useRef } from "react"
// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
// import { faArrowDown } from "@fortawesome/free-solid-svg-icons"
import { Link } from "react-router-dom"
import useFetch from "./useFetch"
import Axios from "axios"

export default function Homepage() {
  const [body, setBody] = useState("")
  const [sortedData, setSortedData] = useState("")
  const [data, setData] = useState("")
  const [css, setCss] = useState("")
  const [flash, setFlash] = useState(null)
  const posts = useFetch("http://localhost:5000/api/data")
  const firstRender = useRef(true)

  useEffect(() => {
    let test = JSON.parse(window.localStorage.getItem("user"))
    console.log(test)
    setData(posts)
  }, [posts])

  useEffect(() => {
    if (firstRender.current) {
      firstRender.current = false
      return
    }
    data.sort(function (a, b) {
      return new Date(b.date) - new Date(a.date)
    })
    setSortedData(data)
  }, [data])

  const handleSubmit = (e) => {
    e.preventDefault()
    Axios.post("http://localhost:5000/api/react-create-post", { text: body }, { withCredentials: true })
      .then((res) => {
        setSortedData((prevArray) => [res.data.post, ...prevArray])
        setFlash("Successfully created post.")
        setCss("success-msg")
        setBody("")
      })
      .catch((err) => {
        setCss("error-msg")
        setFlash("Field cannot be left blank.")
      })
  }

  const handleClick = (e) => {
    e.preventDefault()
    e.target.parentElement.children[1]
  }

  return (
    <div>
      <center>
        <div className="create-container">
          <div className="posts-title">Create Post</div>
          <form id="theForm" onSubmit={(e) => handleSubmit(e)}>
            <textarea onChange={(e) => setBody(e.target.value)} value={`${body}`} id="theInput" className="post-input" name="text" type="text"></textarea>
            <button className="submit-btn">POST</button>
          </form>
        </div>
        <div id="postsContainer" className="posts-container">
          <div className="posts-title">Latest Posts</div>
          {flash ? <div className={css}>{flash}</div> : console.log()}
          <div id="postInput">
            {sortedData &&
              sortedData.map((item) => {
                return (
                  <div className="post-container" key={item._id}>
                    <Link className="a" to={`/user/${item.author}`}>
                      <h3 className="author">{item.author}</h3>
                    </Link>
                    <div className="date">{item.date.toLocaleString()}</div>
                    <div className="options-cont">
                      <button onClick={(e) => handleClick(e)} id="optionsBtn" className="options-btn">
                        <i className="fas fa-ellipsis-v"></i>
                      </button>
                      <button data-author={`${item.author}`} data-id={`${item._id}`} data-text={`${item.body}`} id="editBtn" className="edit inside-btn invisible">
                        Edit
                      </button>
                      <button data-author={`${item.author}`} data-id={`${item._id}`} id="deleteBtn" className="delete inside-btn invisible">
                        Delete
                      </button>
                      <br></br>
                    </div>
                    <p className="body-text">{item.body}</p>
                  </div>
                )
              })}
          </div>
        </div>
      </center>
    </div>
  )
}

就我而言,使用 state 作为 className 会删除或更改“sortedData”数组中每个项目的 CSS 并显示所有项目的菜单。我只想显示其中一项的菜单。

【问题讨论】:

  • 这是将元素分解为它们自己的组件的好时机,这将不再需要将项目数据存储为数据属性,而是作为每个项目中的状态(或提升到父级,如果需要)。
  • 什么课?在什么元素上? (e.target.parentElement.children[1] 将是编辑按钮或undefined,这取决于用户在按钮内单击的位置。)您使用的是类组件还是挂钩?

标签: javascript css reactjs


【解决方案1】:

作为pilchard said,您可能希望每个组件都具有自己的“显示”状态,或者至少是“显示”属性。

就我而言,使用 state 作为 className 会删除或更改“sortedData”数组中每个项目的 CSS 并显示所有项目的菜单。我只想显示其中一项的菜单。

如果您在 state 中使用 single 标志,那将是正确的。但是,改为使用 set 标志,每个菜单一个标志,可能由item._id 键入。

假设你不做重构 pilchard(我)建议:

你没有向我们展示足够的代码让我知道你使用的是类组件还是函数组件,所以我将猜测带有钩子的函数组件。如果是这样,初始状态将是:

const [showing, setShowing] = useState(new Set());

然后在渲染时,你会分配类:

<theElement className={showing.has(item._id) ? "class-if-any-to-show-it" : "class-if-any-to-not-show-it" ...

要切换,请在按钮中传递 ID:

<button onClick={(e) => handleClick(e, item._id)}

然后根据需要更新状态:

const handleClick = (e, id) => {
    e.preventDefault()
    setShowing(showing => {
        showing = new Set(showing);
        if (showing.has(id)) {
            showing.delete(id);
        } else {
            showing.add(id);
        }
        return showing;
    });
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 2019-07-06
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多