简体   繁体   中英

Warning: Function components cannot be given refs warning in React using forwardRef

I'm new to React and the Hooks. I was trying to implement a datepicker from react-datepicker into my component, and it comes with a predetermined input element but I wanted to change it with an icon from FontAwesome so I used his custom-input for it.

This is the code

  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/>}
        />
      );
    };

The code is working and the input is changed for an icon from FontAwesome but the problem is that I receive a warning in console.

How is this happening?

also I found this solution but I don't know how is working.

  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}/>}
        />
      );
    };

I added the ref variable which returns createRef() and putting in the <IconInput/> this ref={ref} then deleting the ref from inside forwardRef() . This will give me no warnings... But how this works?

You should pass the ref you got from the second parameter of React.forwardRef to the FontAwesome component. The problem is that the font awesome library doesn't have a ref prop, it has forwardedRef.

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

The reason for the error you got is that when you pass ref to a class component, it returned the class instance, but in functional component, it has no meaning unless you use forwardRef. To help developers, React shows a warning in the console in those cases (passing ref to functional components that doesn't use forwardRef). When you passed ref to FontAwesome, which is a functional component that doesn't use forwardRef, it showed you this error. When you removed the ref, it removed the error, but if you'll look, the ref you've got from IconInput is empty.

Also, in functional components you should use useRef() instead of createRef , like so:

const ref = useRef();

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

And just one last thing - You should move const IconInput =... to be outside of the component, because now you re-create the component itself on every render, which will cause problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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