React中根据用户选择的下拉框与图片生成指定格式JSON的实现问题
实现方案
1. 现有问题修复
- 移除
option标签上重复的onChange事件,select标签已经绑定了变更处理函数,option上的监听无效 - 合并两个独立表单,不需要为两个下拉框分别做提交逻辑
- 修复复选框ID重复问题,之前所有复选框都用了同一个ID
myCheckbox1,会导致点击任意标签都只触发第一个复选框 - 修复
handleSubmit异步取值问题,axios请求是异步的,不能在then外部直接取接口返回值
2. 新增选中图片状态管理
在state中新增selectedImages数组存储用户勾选的图片路径:
this.state = { // 原有state保持不变 selectedImages: [] }
3. 新增复选框勾选处理函数
handleImageCheck = (e, imgPath) => { if (e.target.checked) { this.setState(prev => ({ selectedImages: [...prev.selectedImages, imgPath] })) } else { this.setState(prev => ({ selectedImages: prev.selectedImages.filter(path => path !== imgPath) })) } }
4. 调整图片渲染逻辑
{filterDropdown.map((course) => ( <div className="col-2" key={course.id}> <input type="checkbox" id={`imgCheckbox_${course.id}`} onChange={(e) => this.handleImageCheck(e, course.path)} /> <label htmlFor={`imgCheckbox_${course.id}`} className="labell"> <img src={course.path} height="80" className="card-img-top img-responsive" alt="img" /> </label> </div> ))}
5. 生成目标格式JSON
新增生成JSON的方法,按照你要求的格式输出:
generateJson = () => { if (!this.state.course || !this.state.model || this.state.selectedImages.length === 0) { alert('请先选择数据集、模型并勾选至少一张图片') return } // 按要求生成合法JSON结构 const result = this.state.selectedImages.map(imgUrl => ({ data: { dropdown1: this.state.course, dropdown2: this.state.model, 'image url': imgUrl } })) // 控制台输出测试 console.log(JSON.stringify(result, null, 2)) // 弹出预览窗口 const newWin = window.open("about:blank", "result", "width=400,height=400"); newWin.document.write(`<pre>${JSON.stringify(result, null, 2)}</pre>`) }
修改后完整代码
import React from "react"; import axios from 'axios' import '../Login.css' export default class Inference extends React.Component { constructor(props) { super(props); this.state = { courses: [], course: "", inferenceout: [], model: "", isLoading: false, selectedImages: [], options: [ { label: "resnet-50torch", value: "resnet-50torch" }, { label: "densenet_onnx", value: "densenet_onnx" }, { label: "inception_graphdef", value: "inception_graphdef" }, ], }; this.handleChange = this.handleChange.bind(this); this.handleChangeCourse = this.handleChangeCourse.bind(this); this.click = this.click.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.handleImageCheck = this.handleImageCheck.bind(this); this.generateJson = this.generateJson.bind(this); } handleChange(e) { console.log("Model Selected!!"); this.setState({ model: e.target.value }); } handleChangeCourse = (event) => { // 切换数据集时清空已选图片 this.setState({ course: event.target.value, selectedImages: [] }); }; handleImageCheck = (e, imgPath) => { if (e.target.checked) { this.setState(prev => ({ selectedImages: [...prev.selectedImages, imgPath] })) } else { this.setState(prev => ({ selectedImages: prev.selectedImages.filter(path => path !== imgPath) })) } } generateJson = () => { if (!this.state.course || !this.state.model || this.state.selectedImages.length === 0) { alert('请先选择数据集、模型并勾选至少一张图片') return } const result = this.state.selectedImages.map(imgUrl => ({ data: { dropdown1: this.state.course, dropdown2: this.state.model, 'image url': imgUrl } })) console.log(JSON.stringify(result, null, 2)) const newWin = window.open("about:blank", "result", "width=400,height=400"); newWin.document.write(`<pre>${JSON.stringify(result, null, 2)}</pre>`) // 可自行扩展存储到localStorage或者提交到后端 } getUnique(arr, comp) { const unique = arr .map((e) => e[comp]) .map((e, i, final) => final.indexOf(e) === i && i) .filter((e) => arr[e]) .map((e) => arr[e]); return unique; } click() { this.setState({ isLoading: true }); axios .get(`http://localhost:5000/model-list`) .then((res) => { this.setState({ inferenceout: res.data , isLoading: false, }) let newWin = window.open("about:blank", "res.data", "width=400,height=400"); newWin.document.write(JSON.stringify(res.data)) localStorage.setItem("apiData", JSON.stringify(res.data)); var data = JSON.parse(localStorage.getItem("apiData")); console.log(data) }) } handleSubmit(event) { event.preventDefault(); axios.post('http://localhost:5000/getmodel', { model: this.state.model, dataset:this.state.course }) .then((res) => { localStorage.setItem("apiData1", JSON.stringify(res.data)); var data = JSON.parse(localStorage.getItem("apiData1")); console.log(data) }); } componentDidMount() { axios .get(`http://localhost:5000/files`) .then((response) => this.setState( { courses: response.data }, ) ) .catch((err) => console.log(err)) } render() { const uniqueCouse = this.getUnique(this.state.courses, "dataset"); const { courses, course, options } = this.state; const filterDropdown = courses.filter(function (result) { return result.dataset === course; }); return ( <div className="container"> <form onSubmit={this.handleSubmit}> <div className="row"> <div className="col-6" style={{ paddingBottom: "100px", paddingTop: "20px", alignItems: "center", }} > <label className="" style={{ paddingTop: "5px", marginTop: "40px" }} > Dataset <select className="custom-select" value={this.state.course} onChange={this.handleChangeCourse} style={{ paddingTop: "5px", marginTop: "10px" }} > <option value="">--Select--</option> {uniqueCouse.map((course) => ( <option key={course.id} value={course.dataset}> {course.dataset} </option> ))} </select> </label> </div> <div className="col-6" style={{ paddingBottom: "100px", paddingTop: "20px", alignItems: "center", }} > <label className="" style={{ paddingTop: "5px", marginTop: "40px" }} > Model <select className="custom-select" name="example" value={this.state.model} onChange={this.handleChange} style={{ paddingTop: "5px", marginTop: "10px" }} > <option value="">--Select--</option> {options.map((option) => ( <option key={option.value} value={option.value} > {option.label} </option> ))} </select> </label> </div> <div className="col-12 mb-3"> <button type="submit" className="btn" > 确认选择 </button> </div> {filterDropdown.map((course) => ( <div className="col-2" key={course.id}> <input type="checkbox" id={`imgCheckbox_${course.id}`} onChange={(e) => this.handleImageCheck(e, course.path)} /> <label htmlFor={`imgCheckbox_${course.id}`} className="labell"> <img src={course.path} height="80" className="card-img-top img-responsive" alt="img" /> </label> </div> ))} <button type="button" onClick={this.click} disabled={this.state.isLoading} className="btn btn-success" style={{ marginLeft:"45%" ,marginBottom:"10px"}} > Inference </button> <button type="button" className="btn btn-primary" style={{ marginLeft:"45%", marginBottom:"10px"}} onClick={()=> window.open("/visual", "data","width=400,height=400")} > Get Output </button> <button type="button" className="btn btn-secondary" style={{ marginLeft:"45%"}} onClick={this.generateJson} > 生成JSON </button> </div> </form> </div> ); } }
内容的提问来源于stack exchange,提问作者Karthikeyan M
相关产品推荐
相关产品推荐

