0

I need to share a File object created via a file input, from a child component (the code below) to its parent, using a function passed as a prop from the parent component.

import React, { Component } from "react";

class FileInput extends Component {
  watchFile = event => {
    event.stopPropagation();
    event.preventDefault();
    const file = event.target.files[0];
    const metadata = {
      contentType: file.type
    };
    this.props.getKBISinput({ file, metadata });
  };
  render() {
    return (
      <label className="btn btn-default">
        Browse<input
          type="file"
          style={{ display: "none" }}
          onChange={this.watchFile}
        />
      </label>
    );
  }
}

export default FileInput;

Here is the passed function:

  getKBISinput = kBis => {
    this.setState({ kBis });
  };

An the parent component's state:

  state = {
    // ...
    kBis: {
      file: {},
      metadata: ""
    }
  };

This doesn't work. Once set in the parent component's state, I try to view the File object from the React devtools.

It's stuck like that, I can't open it from the tree view: buggy react devtools

And I get this console error: Console error

Never had to share a special type of object between components. What's the ideal practice in this case?

Lucas
  • 93
  • 8
  • Can you show the function you pass to `getKBISinput` in the parent component ? – Dyo Feb 05 '18 at 11:07
  • @Dyo added some context. – Lucas Feb 05 '18 at 11:27
  • It seems you cannot store a file in an object, what is doing your app with this file ? (if you really want to store it you'll need to convert it first) – Dyo Feb 05 '18 at 12:51
  • I need to store this object (which I consider to be the reference to the file on the user's disk, not the file itself) in order to send it with the rest of my form once I submit it. – Lucas Feb 05 '18 at 13:06

1 Answers1

0

The line this.props.getKBISinput({file, metadata}) seems incorrect since you are passing object without key value pair. Pass them as arguments.

In parent component.

getKBISinput(file, metadata){
    this.setState({ kBis: {
           file: file,
           metadata: metadata
        } 
      });
};

<FileInput getKBISinput={(file, metadata)=>this.getKBISinput(file, metadata)}/>

In child component:

watchFile = event => {
    event.stopPropagation();
    event.preventDefault();
    const file = event.target.files[0];
    const metadata = {
      contentType: file.type
    };
    this.props.getKBISinput(file, metadata);
  };
Rishabh
  • 1,205
  • 1
  • 11
  • 20
  • This is an ES6 feature: [Object literals](http://www.benmvp.com/learning-es6-enhanced-object-literals/) – Lucas Feb 05 '18 at 12:47