首页 > 解决方案 > 警告:在 React 中使用 forwardRef 无法给函数组件提供 refs 警告

问题描述

我是 React 和 Hooks 的新手。我试图在我的组件中实现一个来自react-datepicker的日期选择器,它带有一个预定的输入元素,但我想用 FontAwesome 的图标来改变它,所以我使用了他的自定义输入

这是代码

  const Task = () => {
      const [startDate, setStartDate] = useState(new Date());
      const IconInput = forwardRef(
        ({ value, onClick }, ref) => (
          <FontAwesome icon={faCalendarAlt} className="example-custom-input" onClick={onClick} ref={ref}>
            {value}
          </FontAwesome>
        ),
      );
      return (
        <DatePicker
          selected={startDate}
          onChange={date => setStartDate(date)}
          customInput={<IconInput/>}
        />
      );
    };

代码正在运行,并且从 FontAwesome 更改了图标的输入,但问题是我在控制台中收到警告。

这是怎么回事?

我也找到了这个解决方案,但我不知道它是如何工作的。

  const Task = () => {
      const [startDate, setStartDate] = useState(new Date());

      const ref = createRef();

      const IconInput = forwardRef(
        ({ value, onClick }, ref) => (
          <FontAwesome icon={faCalendarAlt} className="example-custom-input" onClick={onClick}>
            {value}
          </FontAwesome>
        ),
      );
      return (
        <DatePicker
          selected={startDate}
          onChange={date => setStartDate(date)}
          customInput={<IconInput ref={ref}/>}
        />
      );
    };

我添加了ref返回的变量createRef()并放入<IconInput/>this然后从里面ref={ref}删除。这不会给我任何警告......但是这是如何工作的?refforwardRef()

标签: reactjsreact-hooksreact-datepickeruse-ref

解决方案


您应该将从第二个参数获得的 ref 传递React.forwardRefFontAwesome组件。问题是字体真棒库没有 ref 道具,它有 forwardedRef。

const IconInput = forwardRef(
    ({ value, onClick }, ref) => (
        <FontAwesome icon={faCalendarAlt} className="example-custom-input" onClick={onClick} forwardedRef={ref}>
            {value}
        </FontAwesome>
    ),
);

你得到错误的原因是当你将ref传递给一个类组件时,它返回了类实例,但在功能组件中,除非你使用forwardRef,否则它没有任何意义。为了帮助开发人员,React 在这些情况下会在控制台中显示警告(将 ref 传递给不使用 forwardRef 的功能组件)。当您将 ref 传递给 FontAwesome(一个不使用 forwardRef 的功能组件)时,它会向您显示此错误。当您删除 ref 时,它删除了错误,但如果您看一下,您从 IconInput 获得的 ref 是空的。

此外,在功能组件中,您应该使用useRef()而不是createRef,如下所示:

const ref = useRef();

return (
    <DatePicker
        selected={startDate}
        onChange={date => setStartDate(date)}
        customInput={<IconInput ref={ref}/>}
    />
);

最后一件事 - 您应该移到const IconInput = ...组件之外,因为现在您在每次渲染时都重新创建组件本身,这会导致问题。


推荐阅读