Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function components cannot have refs. Did you mean to use React.forwardRef()?

Hi I am trying to choose file form my computer and display the file name on input field but I am getting this error

Function components cannot have refs. Did you mean to use React.forwardRef()

https://stackblitz.com/edit/react-aogwkt?file=bulk.js

here is my code

import React, { Component } from "react";
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  IconButton,
  Input,
  InputAdornment,
  withStyles
} from "@material-ui/core";
import Attachment from "@material-ui/icons/Attachment";
import CloudDownload from "@material-ui/icons/CloudDownload";
const BulkUpload = props => {
  const { classes } = props;
  return (
    <div className="App">
      <input
        id="file_input_file"
        className="none"
        type="file"
        ref={'abc'}
      />
      <Input
        id="adornment-attachment"
        type="text"
        fullWidth

        endAdornment={
          <InputAdornment position="end">
            <IconButton
              aria-label="Toggle password visibility"
              onClick={e => {
              // this.refs['abc'].click();
              }}
              className="login-container__passwordIcon"
            >
              <Attachment />
            </IconButton>
          </InputAdornment>
        }
      />
    </div>
  );
};

export default BulkUpload;

I just wanted to show selected file name on input field

like image 849
user944513 Avatar asked Mar 20 '19 07:03

user944513


People also ask

How do you use React forwardRef in functional components?

React forwardRef is a method that allows parent components pass down (i.e., “forward”) refs to their children. Using forwardRef in React gives the child component a reference to a DOM element created by its parent component. This then allows the child to read and modify that element anywhere it is being used.

Why do we need React forwardRef?

The forwardRef method in React allows parent components to move down (or “forward”) refs to their children. ForwardRef gives a child component a reference to a DOM entity created by its parent component in React. This helps the child to read and modify the element from any location where it is used.

How do you give ref to the functional component React?

To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.


3 Answers

If you are using v16.8.0 or above of react you can make use of hooks useRef method to define a ref and use it

import React, { Component, useRef } from "react";
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControl,
  IconButton,
  Input,
  InputAdornment,
  withStyles
} from "@material-ui/core";
import Attachment from "@material-ui/icons/Attachment";
import CloudDownload from "@material-ui/icons/CloudDownload";
const BulkUpload = props => {
  const { classes } = props;
  const inputRef = useRef(null);
  return (
    <div className="App">
      <input
        id="file_input_file"
        className="none"
        type="file"
        ref={inputRef }
      />
      <Input
        id="adornment-attachment"
        type="text"
        fullWidth

        endAdornment={
          <InputAdornment position="end">
            <IconButton
              aria-label="Toggle password visibility"
              onClick={e => {
                 inputRef.current.click();
              }}
              className="login-container__passwordIcon"
            >
              <Attachment />
            </IconButton>
          </InputAdornment>
        }
      />
    </div>
  );
};

export default BulkUpload;

If you are using a lower version between v16.3.0 and v16.8.0, you can make use of React.createRef

const BulkUpload = props => {
  const { classes } = props;
  const inputRef = React.createRef(null);
  return (
    <div className="App">
      <input
        id="file_input_file"
        className="none"
        type="file"
        ref={inputRef}
      />
      <Input
        id="adornment-attachment"
        type="text"
        fullWidth

        endAdornment={
          <InputAdornment position="end">
            <IconButton
              aria-label="Toggle password visibility"
              onClick={e => {
                 inputRef.current.click();
              }}
              className="login-container__passwordIcon"
            >
              <Attachment />
            </IconButton>
          </InputAdornment>
        }
      />
    </div>
  );
};

export default BulkUpload;

Or else if you are using an even lower version then you need to convert your component into class component and use ref using callback refs like

class BulkUpload extends Component {
   render() {
      const { classes } = this.props;
      return (
        <div className="App">
          <input
            id="file_input_file"
            className="none"
            type="file"
            ref={(ref) => this.inputRef = ref}
          />
          <Input
            id="adornment-attachment"
            type="text"
            fullWidth

            endAdornment={
              <InputAdornment position="end">
                <IconButton
                  aria-label="Toggle password visibility"
                  onClick={e => {
                     this.inputRef.click();
                  }}
                  className="login-container__passwordIcon"
                >
                  <Attachment />
                </IconButton>
              </InputAdornment>
            }
          />
        </div>
      );
    };
}

export default BulkUpload;
like image 193
Shubham Khatri Avatar answered Oct 19 '22 18:10

Shubham Khatri


The problem here is that you are using a very outdated method of using refs. You need to change your code to something like this

const BulkUpload = props => {   const { classes } = props;   let inputRef = React.createRef();   return (     <div className="App">       <input         id="file_input_file"         className="none"         type="file"         ref={inputRef}       />       <Input         id="adornment-attachment"         type="text"         fullWidth          endAdornment={           <InputAdornment position="end">             <IconButton               aria-label="Toggle password visibility"               onClick={e => {                 inputRef.current.click()               }}               className="login-container__passwordIcon"             >               <Attachment />             </IconButton>           </InputAdornment>         }       />     </div>   ); }; 
like image 20
ManavM Avatar answered Sep 27 '22 17:09

ManavM


const renderItem = ({ item, index }) => {
            return (
            <>          
            <Item
                key={item.Id}
                item={item}
                index={index}
            />
            </>
        );
    };


   using fragment solve this issue 
    <> 
    </> 
like image 1
Keshav Gera Avatar answered Oct 19 '22 17:10

Keshav Gera