【问题标题】:React Hooks - "Function components cannot be given refs" with useRefReact Hooks - “功能组件不能被给予参考”与 useRef
【发布时间】:2019-11-03 09:39:53
【问题描述】:

我正在使用 styled-components、FontAwesome 和 React Hooks 为标题/导航栏创建图标和标签单元 (Box.js)。在 Box 内有一个 Container,其中包含 IconLabel。我希望IconLabel 在您将鼠标悬停在其中任何一个 上时一起更改颜色,这就是为什么我将onMouseOveronMouseOut 放在Container 组件上的原因。我松散地关注this guide 来实现类似的东西。

在点击链接之前,我尝试了这个 useHover 钩子,它没有给我错误消息但没有产生任何效果(当我悬停在上面时,甚至没有 console.log 输出)。

我已经用谷歌搜索了错误消息,但看起来 Github 上现有的 StackOverflow 帖子和 React 问题没有处理 Hooks。其中报告的错误消息也略有不同:Warning: Stateless function components cannot be given refs. Attempts to access this ref will fail.我的错误消息没有“无状态”一词。

这里的工作示例:https://codesandbox.io/s/q7rwe

预期:当鼠标悬停在任一子元素上时,Container(即IconLabel)的所有子元素都变为绿色。

实际:我收到以下错误消息 -

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `Box`.
    in Icon (created by Box)
    in div (created by Context.Consumer)
    in StyledComponent (created by styled.div)
    in styled.div (created by Box)
    in Box (created by App)
    in div (created by App)
    in App

【问题讨论】:

  • 这就是 forwardRef 的样子,以防万一codesandbox.io/embed/useref-error-7tere。问题是 FontAwesomeIcon 不支持 ref。有一个 pull request 应该会在合并后尽快解决此问题。
  • 感谢@AlexanderStaroselsky 的链接!不知道 FontAwesome 问题。

标签: reactjs font-awesome react-hooks styled-components


【解决方案1】:

您当前的方法存在一些缺陷。

首先,你不应该给函数组件一个ref

但是,即使你这样做了,你也不能使用ref 来改变你当前结构的颜色,因为useEffect 将在渲染后被激活并立即使组件的颜色变为绿色,因为ref.current会存在的。

您已经拥有isHovered 状态。只需用它来改变颜色。

我已更新您的代码以更好地实现您想要的行为。试试看!

Box.js

const Box = () => {
  const [isHovered, setHovered] = useState(false);

  return (
    <Container
      onMouseOver={() => setHovered(true)}
      onMouseOut={() => setHovered(false)}
    >
      <Icon isHovered={isHovered} />
      <Label isHovered={isHovered} />
    </Container>
  );
};

图标.js

import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCoffee } from "@fortawesome/free-solid-svg-icons";
const Icon = props => {
  return (
    <FontAwesomeIcon
      icon={faCoffee}
      color={props.isHovered ? "green" : "black"}
    />
  );
};

export default Icon;

标签.js

import React from "react";
const Label = props => {
  return (
    <p style={{ color: props.isHovered ? "green" : "black" }}>
      Label goes here
    </p>
  );
};
export default Label;

https://codesandbox.io/embed/useref-error-xjf48

【讨论】:

  • 谢谢@bkm412 @Ryan!我想知道您是否可以澄清为什么不能将ref 提供给功能组件?我认为这就是 useRef 被包含在新的 Hook API 中的意义所在。
  • useRef 用于访问 HTML 元素。如控制输入或获取 div 的滚动高度等。 useRef 不适用于获取功能组件。 reactjs.org/docs/refs-and-the-dom.html
猜你喜欢
  • 2020-06-18
  • 2021-09-16
  • 2020-08-01
  • 2020-02-13
  • 2019-10-22
  • 2019-12-15
  • 1970-01-01
  • 2021-10-02
相关资源
最近更新 更多