React上传图片后预览不显示 如何补充代码实现即时预览
React 图片上传即时预览实现方案
问题说明
需要实现图片选择后即时显示预览效果,现有代码仅完成文件选择、S3 上传逻辑,缺少本地预览相关处理。
现有代码
上传组件 JSX 片段
<label className="input_label_profile">Image</label> <br/> <label style={{backgroundColor:'#eeeeee',borderRadius:'0px',border:'1px dashed #999999',height:'8vw',width:'8vw'}} className="add-user-upload-image add-user-upload-image-2"> <Form.Item name="experience_image" style={{height:'0px'}}> <Input accept="image/*" id="raised-button-file" multiple type="file" onChange={(event) => { this.addImage(event.target.files[0]) } } style={{height:'0px'}} /> </Form.Item> <PlusOutlined /> <br/> <br/> <br/> <span style={{cursor: 'pointer',marginTop:'5vw'}}> UPLOAD IMAGE</span> </label>
现有 addImage 方法
addImage = (image) => { console.log("image name:",image); const file = image this.setState({ file: file, fileNameLocal:image.name, }); let img_type = file.type this.setState({ img_type: img_type }) const uploadParams = { files: [ { requestType: 'CandidateProfile', contentType: img_type, }, ], }; APIManager.preSignedUrl(uploadParams).then((resp) => { if (resp.status === 200) { console.log(resp) this.setState({ uploadUrl:resp.data[0].url, fileName:resp.data[0].fileName, experience_image:resp.data[0].fileName }) this.uploadOnS3(file); } }); }
修改步骤
- 组件 state 初始化时新增
previewUrl字段,默认值为空字符串,用于存储本地临时预览地址 - 修改
addImage方法,选中文件后通过FileReader读取本地文件生成 base64 格式的临时预览地址,存入 state,不需要等待接口返回或上传完成 - 调整上传区域渲染逻辑:存在预览地址时隐藏原上传提示,渲染预览图片;未选择文件时保持原有上传提示样式
- 增加空值判断,避免用户取消选文件时触发报错
修改后完整代码
调整后的 addImage 方法
addImage = (image) => { // 处理用户取消选文件的场景 if (!image) return console.log("image name:",image); const file = image // 生成本地预览地址 const reader = new FileReader() reader.onload = (e) => { this.setState({ previewUrl: e.target.result }) } reader.readAsDataURL(file) this.setState({ file: file, fileNameLocal:image.name, }); let img_type = file.type this.setState({ img_type: img_type }) const uploadParams = { files: [ { requestType: 'CandidateProfile', contentType: img_type, }, ], }; APIManager.preSignedUrl(uploadParams).then((resp) => { if (resp.status === 200) { console.log(resp) this.setState({ uploadUrl:resp.data[0].url, fileName:resp.data[0].fileName, experience_image:resp.data[0].fileName }) this.uploadOnS3(file); } }); }
调整后的上传组件 JSX
<label className="input_label_profile">Image</label> <br/> <label style={{ backgroundColor:'#eeeeee', borderRadius:'0px', border:'1px dashed #999999', height:'8vw', width:'8vw', position: 'relative', overflow: 'hidden' }} className="add-user-upload-image add-user-upload-image-2" > <Form.Item name="experience_image" style={{height:'0px'}}> <Input accept="image/*" id="raised-button-file" multiple type="file" onChange={(event) => { this.addImage(event.target.files[0]) } } style={{height:'0px'}} /> </Form.Item> {this.state.previewUrl ? ( <img src={this.state.previewUrl} alt="upload preview" style={{ width: '100%', height: '100%', objectFit: 'cover', position: 'absolute', top: 0, left: 0 }} /> ) : ( <> <PlusOutlined /> <br/> <br/> <br/> <span style={{cursor: 'pointer',marginTop:'5vw'}}> UPLOAD IMAGE</span> </> )} </label>
补充说明
- 本地预览使用浏览器生成的临时 base64 地址,选完文件即可显示,无网络等待
- 预览图样式可根据自身UI需求调整,
objectFit: 'cover'是为了保证图片不变形、铺满上传区域 - 重新选择图片时会自动覆盖原有预览地址,不需要额外处理替换逻辑
- 如果需要支持删除已选图片,在对应重置逻辑里把
previewUrl重置为空字符串即可
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

