Skip to content
Advertisement

react createref was returning the error due to wrong implementation

This is the edited question after submitting the answer

In this code, my file browser will now directly open but when I am submiting the final button then I am not getting the updated state.

uploadImage() will be converting the image to base 64 and then update the value on the state.

uploadCode() will be used to final send the data after clicking on submit button. I have checked that I am not getting the updated value of state in this function according to this logic i.e label & htmlFor.

My earlier logic was fine when click on upload image div then set the state variable show image from false to true; Choose file button only visible when state is true. Rest all implementation is same and that was working fine. But now I am be able to getting the updated state that is why when submit button click I am not getting the image as state is not updated.

 constructor(props, context) {
    super(props, context);
    this.inputFile = React.createRef()
    this.onButtonClick = this.onButtonClick.bind(this);
}
uploadImage = (e) => {
    console.log('function called')
/*************New Edit*************/
// getting the image through base64 string and then update it on state;
this.setState({image: myBase64String}, () => { console.log(this.state.image )});
// Return the string through above console
  }

uploadCode = () => {
const {image} = this.state;
console.log(image);//returns undefined;
}
render(){
 return (
    <div><Button onClick={()=>this.uploadCode()} >SUBMIT</Button></div>
      <div className={cx(styles['display-tablecell'], styles['pl-lg'])}>
        <FormControl
          style={{display: 'none'}}
          id="formControlsFile"
          type="file"
          label="File"
          onChange={this.uploadImage}
          name="image"
          ref={this.inputFile}
        />
        <label
          style={{display: 'inline-block'}}
          // onClick={this.onButtonClick}
          htmlFor="formControlsFile" <---- binding to the input tag using the same id
        >
          <i className={cx(fontStyles.fa, fontStyles['fa-image'])} />
        </label>
      </div>
)
}

Advertisement

Answer

You are trying to open the file explorer when user clicks on the <span />. However, you do not need to simulate the click behaviour to achieve that. You can make use of the html <label /> tag to bind the onclick functionality of <input type="file" />. Here’s how –

class App extends Component {
  constructor(props, context) {
    super(props, context)
    /* You won't need these
    this.inputFile = React.createRef()
    this.onButtonClick = this.onButtonClick.bind(this)
    */
  }

  uploadImage = (e) => {
    console.log('function called')
/*************New Edit*************/
// getting the image through base64 string and then update it on state;
this.setState({image: myBase64String}, () => { console.log(this.state.image )});
// Return the string through above console
  }

  /* You won't need these
  onButtonClick = () => {
    console.log('div clicked')
    this.inputFile.current.click()
  }
  */
uploadCode = () => {
const {image} = this.state;
console.log(image);//returns undefined;
}
  render() {
    return (
<div><Button onClick={()=>this.uploadCode()} >SUBMIT</Button></div>
      <div className={cx(styles['display-tablecell'], styles['pl-lg'])}>
        <FormControl
          style={{display: 'none'}}
          id="formControlsFile"
          type="file"
          label="File"
          onChange={this.uploadImage}
          name="image"
          ref={this.inputFile}
        />
        <label
          style={{display: 'inline-block'}}
          // onClick={this.onButtonClick}
          htmlFor="formControlsFile" <---- binding to the input tag using the same id
        >
          <i className={cx(fontStyles.fa, fontStyles['fa-image'])} />
        </label>
      </div>
    )
  }
}

You can find more information about <label /> tag here.

Advertisement