React中如何将子组件UploadImage的文件名传递给父组件
React子组件向父组件传递上传文件名的实现方案
问题描述
现有子组件UploadImage.js和父组件Parent.js,需要在图片上传完成后,将上传的文件名传递给父组件,并显示在父组件的uploadFileName状态中。
解决方案:通过回调函数实现父子组件通信
核心思路是父组件向子组件传递一个回调函数,子组件在文件状态更新时调用该回调,将文件名传递给父组件以更新其状态。
1. 修改父组件Parent.js
给UploadImage组件传入回调prop,直接用父组件的setUploadFileName作为回调(它本身就是接收字符串更新状态的函数):
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 onFileNameChange={setUploadFileName} /> <h3 className="m-3">{uploadFileName} </h3> </div> ); }; export default Parent; // 修正原代码导出名错误
2. 修改子组件UploadImage.js
接收父组件传递的onFileNameChange回调,在文件状态变化时调用该回调传递文件名:
import React, { useEffect, useState } from 'react'; import { useDropzone } from 'react-dropzone'; // 接收父组件传入的回调prop const UploadImage = ({ onFileNameChange }) => { const [files, setFiles] = useState([]); const { getRootProps, getInputProps } = useDropzone({ accept: { 'image/*': [] }, onDrop: acceptedFiles => { const newFiles = acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) })); setFiles(newFiles); } }); // 监听files状态变化,将文件名传递给父组件 useEffect(() => { if (files.length > 0) { onFileNameChange(files[0].name); } else { onFileNameChange(""); } }, [files, onFileNameChange]); // preview组件 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} onLoad={() => { URL.revokeObjectURL(file.preview) }} /> </div> </div> )); // 修正清理函数依赖,避免内存泄漏 useEffect(() => { return () => files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files]); 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;
关键说明
- 这是React中最常用的父子组件数据传递方式:父组件传递回调,子组件调用回调传值。
- 使用
useEffect监听files状态,确保无论通过拖拽还是点击选择文件,都能及时传递文件名。 - 修正了原代码中清理函数的依赖数组,避免闭包导致的内存泄漏问题。
内容的提问来源于stack exchange,提问作者MagnusEffect
相关产品推荐
相关产品推荐

