MagnusEffect
MagnusEffect

Reputation: 3905

How to pass a value from child to parent component in reactjs

I had a child component UploadImage.js and parent component Parent.js. I am uploading an image and want to pass the value of file name to the Parent.js component. How can I do so?

UploadImage.js

import React, { useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone';

.
.
.

const UploadImage = () => {

    const [files, setFiles] = useState([]);
    const { getRootProps, getInputProps } = useDropzone({
        accept: {
            'image/*': []
        },
        onDrop: acceptedFiles => {
            setFiles(acceptedFiles.map(file => Object.assign(file, {
                preview: URL.createObjectURL(file)
            })));
        }
    });

    //preview component
    const thumbs = files.map(file => (
        <div style={thumb} className="d-flex flex-row mt-1 col-12 mx-auto" key={file.name}>
            <div style={thumbInner}>
                <img
                    src={file.preview}
                    style={img}
                    // Revoke data uri after image is loaded
                    onLoad={() => { URL.revokeObjectURL(file.preview) }}
                />
            </div>
        </div>
        
    )
    );

    //wanted to pass file[0].name to Parent Component
    console.log(files.length > 0 ? files[0].name : "")


    useEffect(() => {
        // Make sure to revoke the data uris to avoid memory leaks, will run on unmount
        return () => files.forEach(file => URL.revokeObjectURL(file.preview));
    }, []);

    return (
        <section className="container">
            <div {...getRootProps({ className: 'dropzone mx-3 text-center mt-4 mb-2 p-3 bg-light border border-primary border-1 rounded-4 ' })}>
                <input {...getInputProps()} />
                <p className='fw-bold text-primary'>Drag 'n' drop some files here, or click to select files</p>
            </div>
            <aside style={thumbsContainer} className="d-flex flex-row">
                {thumbs}
                
            </aside>
        </section>
    );
}

export default UploadImage;

And my Parent component is like this

import React, { useState} from "react";
import UploadImage from "../components/uploadImage";

const Parent = () => {
  const [uploadFileName, setUploadFileName] = useState("");

  
  return (
    <div className="mx-3 mt-4 mb-2">
      <UploadImage />

      <h3 className="m-3">{uploadFileName} </h3>
    </div>
  );
};

export default UploadButton;

How can I display the file name from UploadImage.js to Parent.js in the uploadFileName state ???

Upvotes: 0

Views: 894

Answers (4)

Anh Le Hoang
Anh Le Hoang

Reputation: 349

You should move const [files, setFiles] = useState([]); to Parents.js and then pass them by Props for UploadImage.js.

// UploadImage Component
    const UploadImage = (props) => {
        const {files, onUpdateFiles} = props;
        const { getRootProps, getInputProps } = useDropzone({
            accept: {
                'image/*': []
            },
            onDrop: acceptedFiles => {
              onUpdateFiles(acceptedFiles.map(file => Object.assign(file, {
                    preview: URL.createObjectURL(file)
                })));
            }
        });
    ...
    }

// Parents component
    const Parent = () => {
      const [files, setFiles] = useState([]);
      return (
        <div className="mx-3 mt-4 mb-2">
          <UploadImage files={files} onUpdateFiles={setFiles}  />
          {files.length > 0 && <h3 className="m-3">{files[0].name}</h3>}
        </div>
      );
    };

Upvotes: 1

Varun Kaklia
Varun Kaklia

Reputation: 376

Hey MagnusEffect you're almost correct, just make these changes- In UploadImage.js-

const UploadImage = ({setUploadFileName}) => {
<input {...getInputProps()} onChange=
{(e)=>setUploadFileName(e.target.files[0].name)} />
}

While in Parent Component just pass setvalues-

const Parent = () => {
const [uploadFileName, setUploadFileName] = useState("");
return (
<div className="mx-3 mt-4 mb-2">
<UploadImage setUploadFileName={setUploadFileName} />
<h3 className="m-3">{uploadFileName} </h3>
</div>
);
}

Hope this code will help to solve your query if you still facing issue, just lemme know i will help you more. Thanks

Upvotes: 1

Mamdasan
Mamdasan

Reputation: 323

you create a function in your parent element like:

const NameSetter = imageName => {
  setUploadFileName(imageName);
}

and then send the NameSetter as a prop to your child element like:

<UploadImage nameHandler={NameSetter} />

and then in your child element you call the nameHandler prop like:

(call this when you get the name, for ex: on the callback of your backend )

props.nameHandler('name of your image');

Upvotes: 1

Kamaraj R
Kamaraj R

Reputation: 11

you can use call back props to update the children to parent.

import React, { useState} from "react";
import UploadImage from "../components/uploadImage";

const Parent = () => {
  const [uploadFileName, setUploadFileName] = useState("");

  
  return (
    <div className="mx-3 mt-4 mb-2">
      <UploadImage setUploadFileName={setUploadFileName}/>

      <h3 className="m-3">{uploadFileName} </h3>
    </div>
  );
};

export default UploadButton;

Then you can set whereever you want to call in child it will update in parent component. You can check through by adding consoling on the parent component.

Upvotes: 1

Related Questions