React 中使用 Refs 改变样式是否很糟糕?

Posted

技术标签:

【中文标题】React 中使用 Refs 改变样式是否很糟糕?【英文标题】:Is it bad to use Refs to change styles in react?React 中使用 Refs 改变样式是不是很糟糕? 【发布时间】:2021-05-03 22:03:49 【问题描述】:

这是一个代码示例,我使用 Ref 来更改样式

import React, useRef, useState, useEffect from 'react'
import S from "./collapsible.module.css"

import PropTypes from 'prop-types'
import  faMinus, faPlus  from '@fortawesome/free-solid-svg-icons'
import  FontAwesomeIcon  from '@fortawesome/react-fontawesome'

function Collapsible(props) 
let myRef = useRef(null);
let buttonRef = useRef(null);
let [ button, setButton] = useState(true)


let Show = () => 
    if(button) 
setButton(false)
buttonRef.current.style.backgroundColor = "#555"
myRef.current.style.maxHeight = myRef.current.scrollHeight + "px";
 else 

setButton(true)
buttonRef.current.style.backgroundColor = "hsl(181, 100%, 11%)"
myRef.current.style.maxHeight =  "0px";




    return (
        <div
        className=S.body
        >
            <button 
            className=S.collapsible
onClick=Show
ref=buttonRef
            > props.label
            
            <div className=S.icon> 
    button? <FontAwesomeIcon icon=faPlus />:
<FontAwesomeIcon icon=faMinus />
</div> 
            </button>
            <div 
            className=S.content
            ref=myRef
            >
<h3>props.body</h3>
            </div>
        </div>
    )

Collapsible.propTypes = 
    label: PropTypes.string,
    body: PropTypes.string,
  
  
  Collapsible.defaultProps = 
    label: '',
    body: "",
  
export default Collapsible

css:

.collapsible 
    display: flex;
    background-color: hsl(181, 100%, 11%);
    color: white;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    outline: none;
    font-size: 15px;
    border-radius: 3px;
    /* margin-bottom: 3px; */
    box-shadow: 0px 1px 5px 1px black;
    margin-top:13px;
  
  .icon
    color:white;
    position:absolute;
    right:50px;
text-align:right;
justify-content: flex-end;

  
  .active, .collapsible:hover 
    background-color: #555;
  
  
  .content 
    padding: 0 18px;
    max-height: 0px;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
    background-color: #f1f1f1;
  

这只是在 React 中复制: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_collapsible_animate

我已经读到使用 Refs 是不好的,尤其是在使用它来更改 DOM 时,但是如果我没有按照“scrollHeight”中显示的确切数量更改样式,那么过渡的速度就会很混乱。

如果有其他方法这还是不好的做法吗?

【问题讨论】:

使用 refs 还不错。有些事情只有通过参考才有可能。如果您需要根据scrollHeight 设置高度,那么这似乎是使用 refs 的一个很好的理由。对于其他样式,您应该使用 CSS 类。 【参考方案1】:

更常见的做法是使用状态值来确定样式,如下所示:

  <button 
     className=S.collapsible 
     onClick=Show 
     style=backgroundColor: button ? "#555" : "hsl(181, 100%, 11%)"
   >
    props.label
    <div className=S.icon>
      button ? (
        <FontAwesomeIcon icon=faPlus />
      ) : (
        <FontAwesomeIcon icon=faMinus />
      )
    </div>
  </button>

或者为您的样式设置一个条件类名:

 <button
    className=`$S.collapsible $
      button ? S.buttonColor : S.anotherButtonColor
    `
    onClick=Show
  >
    props.label
    <div className=S.icon>
      button ? (
        <FontAwesomeIcon icon=faPlus />
      ) : (
        <FontAwesomeIcon icon=faMinus />
      )
    </div>
  </button>

并将 .buttonColor.anotherButtonColor 添加到您的 CSS 模块文件 (collapsible.module.css)。

.buttonColor 
    background-color: #555;


.anotherButtonColor 
    background-color: hsl(181, 100%, 11%);


对于myRef 上的maxHeight,我会这样做:

  <div className=S.content ref=myRef>
    <div style= maxHeight: myRef.current.scrollHeight >
      <h3>props.body</h3>
    </div>
  </div>

【讨论】:

对按钮样式有意义,但是对于由“scrollheight”确定的“maxheight”的其他样式呢? 为此,我将使用第一个示例中显示的 css in js 解决方案。 我添加了一个 sn-p 向您展示我将如何处理它。

以上是关于React 中使用 Refs 改变样式是否很糟糕?的主要内容,如果未能解决你的问题,请参考以下文章

在 Vuex 中不使用操作就提交突变是否很糟糕?

我想改变数据表的样式

React:使用 Refs 修复缺少的依赖警告 useEffect

React组件三大核心属性: state、props、refs

在 React 样式组件上使用 'ref' 不起作用

组件挂载到 React 后如何创建 Refs?