React中如何清除图片URL?图片删除功能失效问题求助
问题原因
删除功能失效的核心原因是:MakeModal组件里的passUrl(preview)被放在了组件函数的顶层——每次组件渲染(包括父组件点击删除后触发的重渲染),这段代码都会执行,把当前子组件保存的preview值重新传给父组件,直接覆盖掉你刚清空的imgUrl。
修改方案
1. 修复MakeModal.jsx的状态传递逻辑
把直接在顶层调用passUrl(preview)的逻辑,移到监听preview变化的useEffect里,只有当preview真正改变时才通知父组件;同时新增重置逻辑,接收父组件的信号清空内部状态:
import React from 'react' import { useEffect, useState, useRef } from 'react'; import styled from 'styled-components'; function MakeModal({ passUrl, reset }) { const fileInput = useRef(null); // 初始值改为null,匹配文件对象的类型逻辑 const [isfile, setIsfile] = useState(null); const [preview, setPreview] = useState(''); // 监听父组件的重置信号,清空自身状态 useEffect(() => { if (reset) { setIsfile(null); setPreview(''); } }, [reset]); // 仅当preview变化时,才传递给父组件 useEffect(() => { passUrl(preview); }, [preview, passUrl]); useEffect(() => { if (isfile) { const objectUrl = URL.createObjectURL(isfile); setPreview(objectUrl); } // 清理函数加判断,避免对null调用revoke报错 return () => { if (isfile) URL.revokeObjectURL(isfile); }; }, [isfile]); const handleButtonClick = e => { fileInput.current.click(); }; const handleChange = e => { setIsfile(e.target.files[0]); console.log(e.target.files[0]); }; return ( <Modal> <div> <div> <div> <div> <div> <div> <input type="file" style={{display:'none'}} ref={fileInput} onChange={handleChange} multiple={true}/> <button onClick={handleButtonClick} className='box9_2_3_3_2'> choose image </button> </div> </div> </div> </div> </div> </div> </Modal> ) } export default MakeModal;
2. 修改Profile.jsx,传递重置信号给子组件
新增resetModal状态,点击删除时先触发子组件清空内部状态,再重置父组件的图片URL:
import React, { useState } from 'react'; import styled from 'styled-components'; import MakeModal from '../components/MakeModal'; function Profile() { const [imgUrl, setImgUrl] = useState(""); // 新增重置状态,用于通知子组件清空自身数据 const [resetModal, setResetModal] = useState(false); const passUrl = (url) => { setImgUrl(url); // 传递新URL后重置reset状态 if (url) setResetModal(false); } const noImg = () => { // 先触发子组件重置内部状态 setResetModal(true); // 再清空父组件的图片URL setImgUrl(""); } console.log("imgUrl", imgUrl) return ( <> <ProfileWrap> <div > <section> <main> <div> <header> <section> <div> <span> <div onClick={noImg}> delete </div> </span> </div> </section> </header> <div> <article> <div> <div> <img src={imgUrl} alt='defaultprofile' className='IMgdiv'/> </div> </div> </article> </div> </div> </main> </section> </div> </ProfileWrap> {/* 传递reset属性给子组件 */} <MakeModal passUrl={passUrl} reset={resetModal}/> </> ) } export default Profile;
内容的提问来源于stack exchange,提问作者MontaKr
相关产品推荐
相关产品推荐

