简体   繁体   English

DOM 元素在 React 上返回 Null

[英]DOM Element Returning Null on React

[EDIT] HAS BEEN FIXED (scroll to bottom) [编辑] 已修复(滚动到底部)

Hi I am trying to select a react element for a functional component, current code:您好我正在尝试 select 一个功能组件的反应元素,当前代码:

const Emoji = (props) => {

  const copyButton = useRef(null);

  function handleHover(e) {
    console.log(this.copyButton); //want to select this element
  }

  function handleMouseOut(e) {

  }

  return(
    <div className="wrapper">
      <div id={"emoji-"+props.id} className="emoji" onMouseOver={handleHover} onMouseOut={handleMouseOut}>
        <Button ref={copyButton} className="copyButton" buttonText="Copy" buttonColour="primary" />
        <Button className="button" buttonText="Information" buttonColour=" " />
        <h1>{props.emojiCharacter}</h1>
        <p>{props.emojiName}</p>
      </div>
    </div>
  );
}

export default Emoji;

I am trying to build an app where when the user hovers over this component the buttons will appear, but when I try to select them I keep getting this error: TypeError: Cannot read property 'copyButton' of undefined我正在尝试构建一个应用程序,当用户将鼠标悬停在此组件上时,按钮将出现,但是当我尝试 select 时,我不断收到此错误: TypeError: Cannot read property 'copyButton' of undefined

It also returns null when I try to document.getElementById as well.当我尝试document.getElementById时,它也会返回 null 。

Any suggestions?有什么建议么? Thanks.谢谢。

FIXED固定的

The problem was due to the element being a custom component and not a default component, otherwise I could've simply just used copyButton.current问题是由于元素是自定义组件而不是默认组件,否则我可以简单地使用copyButton.current

I fixed it by going into the component's jsx and changing the const Button = (props) => { etc } declaration to a我通过进入组件的 jsx 并将const Button = (props) => { etc }声明更改为

const Button = React.forwardRef((props, ref) => (
    <div ref={ref} 
    </div>
));

This article did it https://reactjs.org/docs/forwarding-refs.html这篇文章做到了https://reactjs.org/docs/forwarding-refs.html

copyButton will not be ready on the first cycle of render you need to test before invoking it, and you will need to use copyButton.current copyButton在调用它之前需要测试的第一个渲染周期不会准备好,您将需要使用copyButton.current

const handleMousehover =() =>{
  if(copyButton && copyButton.current){
   // add your code here
  }
}

You will not need to test if the hover is comming from where you used ref={copyButton} , but if it is comming from somewhere else, there is no garenty that it will not be null (or it became null for some reason), so it is a good practice to test it always.您无需测试 hover 是否来自您使用ref={copyButton}的位置,但如果它来自其他地方,则没有任何保证它不会是 null (或者它变成了 Z37BD9786 的 Z37A6259CC0489DFF02)因此,始终对其进行测试是一个好习惯。

You need to use copyButton.current to select your ref={copyButton} Button.您需要使用copyButton.current到 select 您的ref={copyButton}按钮。

The useRef Hook is a function that returns a mutable ref object whose.current property is initialized with the passed argument (initialValue.)The returned object will persist for the full lifetime of the component. useRef Hook 是一个 function,它返回一个可变的 ref object,其.current 属性使用传递的参数(initialValue)进行初始化。返回的 object 将在组件的整个生命周期内持续存在。

const Emoji = (props) => {

  const copyButton = useRef(null);

  function handleHover(e) {
    console.log(copyButton.current); //want to select this element
  }

  function handleMouseOut(e) {

  }

  return(
    <div className="wrapper">
      <div id={"emoji-"+props.id} className="emoji" onMouseOver={handleHover} onMouseOut={handleMouseOut}>
        <Button ref={copyButton} className="copyButton" buttonText="Copy" buttonColour="primary" />
        <Button className="button" buttonText="Information" buttonColour=" " />
        <h1>{props.emojiCharacter}</h1>
        <p>{props.emojiName}</p>
      </div>
    </div>
  );
}

export default Emoji;

NOTE: Coming to the second part of the question.注意:来到问题的第二部分。 You will ned to set styles within your handleHover() function for show and hide logic.您将需要在您的handleHover() function 中设置 styles 用于显示和隐藏逻辑。

Something like this:) Just a demo.像这样的东西:) 只是一个演示。 Implement it as per your requirement根据您的要求实施它

  function handleHover(e) {
    console.log(copyButton.current); 
    copyButton.current.style.display="block";
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM