在 Div 中添加子元素时,虽然使用 UseEffect 触发,但到达 useRef() 当前属性返回未知

Posted

技术标签:

【中文标题】在 Div 中添加子元素时,虽然使用 UseEffect 触发,但到达 useRef() 当前属性返回未知【英文标题】:Reach useRef() Current property return unidentified though using UseEffect to fire when adding a child element inside a Div 【发布时间】:2021-10-17 13:38:34 【问题描述】:

我是反应和理解反应 Hooks 的新手,我正在创建一个小型应用程序,我在其中使用添加 Div 元素动态创建 Bar。为此,我使用 useRef() 和 UseEffect() 在每次更改 div 元素后进行渲染,尽管我知道初始值设置为 null 这就是它返回未识别值的原因,但我真的很想了解我怎么能初始化或任何解决方法。以下是我的代码

import React from "react";
import  useRef, useEffect, useState  from "react";
import "./ExpenseFilter.css";

const ExpenseFilter = (props) => 
  const values = [100, 100, 340, 320, 500, 50, 45, 385, 95, 120, 90, 20];
  const [refState, setrefState] = useState();
  const ref = useRef();

  useEffect(() => 
    console.log(ref.current);
  , [refState]);

  const drawChart = (data, padding) => 
    const max = Math.max.apply(Math, data);
    const chart = ref.current;
    console.log(chart);
    const barwidth =
      (chart.offsetWidth - (values.length - 1) * padding - data.length * 10) /
      data.length;
    console.log(barwidth);
    let left = 0;
    for (let i in data) 
      let newbar = document.createElement("div");
      newbar.setAttribute("class", "bar");
      newbar.style.width = barwidth + "px";
      newbar.style.height = (data[i] / max) * 100 + "%";
      newbar.style.left = left + "px";
      chart.appendChild(newbar);
      left += barwidth + padding + 10;
      props.OnChangeDiv(newbar);
    
  ;
  drawChart(values, 15);

  return (
    <div className="wrapper1">
      <div className="select" tabIndex="1">
        <input
          className="selectopt"
          name="test"
          type="radio"
          id="opt1"
          checked
        />
        <label for="opt1" class="option">
          2019
        </label>
        <input className="selectopt" name="test" type="radio" id="opt2" />
        <label for="opt2" class="option">
          2020
        </label>
        <input className="selectopt" name="test" type="radio" id="opt3" />
        <label for="opt3" class="option">
          2021
        </label>
        <input className="selectopt" name="test" type="radio" id="opt4" />
        <label for="opt4" class="option">
          2022
        </label>
        <input className="selectopt" name="test" type="radio" id="opt5" />
        <label for="opt5" class="option">
          2023
        </label>
      </div>
      <div
        id="chart"
        ref=(el) => 
          setrefState(el);
        
      ></div>
    </div>
  );
;

export default ExpenseFilter;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【问题讨论】:

1.您永远不会分配给 ref.current 2。将 document.createElement 与 React 一起使用是一种非常糟糕的模式。 @sun 不是当前属性持有对象值吗? 2. 是的,你是对的,因为我开始学习 React 需要适应。关于我做错了什么有什么建议吗? 【参考方案1】:

您使用参考的方式有些不对劲。

const ref = useRef()

...

<div ref=ref>Example</div>

// ref.current is now <div>Example</div>

【讨论】:

是的,这就是我想作为参考发送的内容。它完成了这项工作..问题在于初始化..由于 ref 的初始值被设置为 null ,因此 ref current 属性被设置为 unidentified 并且 useEffect 无法重新呈现 ref 的下一个状态。跨度> 也许这就是你要找的reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node。【参考方案2】:

感谢您对此进行调查,我自己解决了这个问题。所以正如我之前所说,分配给 useRef() 的初始值为 null 我们都知道这就是为什么当前属性被设置为未识别的原因。我所做的是我在 ref 上设置了一个条件,如果它是未识别的,那么它应该返回并使用 useState 钩子来触发捕获状态,一旦它改变状态,它就会触发 useEffect() 以重新渲染当前状态.

useEffect(() => 
    if (!ref.current) 
      return;
    
    ref.current = refState;
    console.log(ref.current);
  , [refState]);
  
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div
        id="chart"
        ref=(el) => 
          ref.current = el;
          setrefState(el);
        
      ></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

如果引用,则使用下一个状态。

【讨论】:

以上是关于在 Div 中添加子元素时,虽然使用 UseEffect 触发,但到达 useRef() 当前属性返回未知的主要内容,如果未能解决你的问题,请参考以下文章

响应时,子div超过父div

jquery-创建元素和添加子元素

为JSON对象中的每个数组添加一个(子)按钮元素到div,并为数组中的每个对象添加子按钮(到数组按钮)

jquery怎么清空div的子元素?

JavaScript中,可以用元素的innerHTML直接添加子元素吗?

在没有jQuery的情况下悬停父绝对div的子元素时防止onmouseout