You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

修改说明

  1. 把loadFile和receivedText都改成了App组件的类属性箭头函数,确保函数内部的this固定指向组件实例,可以正常调用this.setState
  2. 移除了原来receivedText里无意义的返回值,拿到新配置后直接调用setState更新状态
  3. 把状态更新后的验证逻辑放到了setState的第二个回调参数中,保证读取到的是更新完成后的最新状态

内容的提问来源于stack exchange,提问作者da_vinci

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 11:06:06