ReactJS加载JSON文件后如何将完整对象数据setState更新组件状态
问题解决说明
该函数取自StackOverflow上我找到的另一个关于从文件加载数据的问题,我找不到原问题链接了,在此注明来源
核心问题点
loadFile是全局独立函数,文件读取完成的回调无法访问React组件实例的this,不能调用setState更新状态FileReader的读取操作、React的setState方法都是异步执行的,调用loadFile后立刻读取state拿到的一定是更新前的旧值
修改后的完整代码
import { Component } from 'react'; // 保留你原有的configData定义逻辑 const configData = /* 你原来的configData赋值内容 */; class App extends Component { state = { integration_time: configData.text_box.integration_time_micro_sec, x_axis_resulotion: configData.text_box.x_axis_resulotion, y_axis_resulotion: configData.text_box.y_axis_resulotion, delay_between_pixels_milisec: configData.text_box.delay_between_pixels_milisec, results_directory: configData.text_box.results_directory, config_file_name: "" }; // 将loadFile移入组件内部,用箭头函数绑定this指向组件实例 loadFile = () => { var input, file, fr; if (typeof window.FileReader !== 'function') { alert("当前浏览器不支持文件API。"); return; } input = document.getElementById('fileInput'); if (!input) { alert("找不到fileinput元素。"); } else if (!input.files) { alert("当前浏览器不支持文件输入的files属性。"); } else if (!input.files[0]) { alert("点击加载前请先选择一个文件。"); } else { file = input.files[0]; fr = new FileReader(); fr.onload = this.receivedText; fr.readAsText(file); } }; // 文件读取完成的回调也作为组件方法 receivedText = (e) => { let lines = e.target.result; var newArr = JSON.parse(lines); console.log(newArr.text_box); var newState ={ integration_time: newArr.text_box.integration_time_micro_sec, x_axis_resulotion: newArr.text_box.x_axis_resulotion, y_axis_resulotion: newArr.text_box.y_axis_resulotion, delay_between_pixels_milisec: newArr.text_box.delay_between_pixels_milisec, results_directory: newArr.text_box.results_directory, config_file_name: "" } console.log(newState); alert("读取到的配置值:" + newState.integration_time); // 直接调用setState更新组件状态,第二个回调是更新完成后触发 this.setState(newState, () => { alert("更新后的state值:" + this.state.integration_time); }); }; handleIntegrationTimeInput = e => { this.setState({integration_time: e.target.value}); }; handleLoadConfigFile = e =>{ this.loadFile(); }; render(){ return( <> <input name="loadedConfigFile" id = 'fileInput' type="file"/> <input name= "loadConfigButton" type= "button" id = "buttonLoad" value= "加载" onClick={this.handleLoadConfigFile} /> </> ); } } export default App;
修改说明
- 把
loadFile和receivedText都改成了App组件的类属性箭头函数,确保函数内部的this固定指向组件实例,可以正常调用this.setState - 移除了原来
receivedText里无意义的返回值,拿到新配置后直接调用setState更新状态 - 把状态更新后的验证逻辑放到了
setState的第二个回调参数中,保证读取到的是更新完成后的最新状态
内容的提问来源于stack exchange,提问作者da_vinci
相关产品推荐
相关产品推荐

