如何在React中加载文件字段的先前状态?

问题描述 投票:0回答:1

我试图为一个音频文件实现一个on-change处理程序,当用户更改文件时,该处理程序会加载文件的先前状态并记录下来。

更具体地说。当用户进入组件时,文件的链接应该显示在窗体字段中,当用户更新文件时,文件的新路径应该被on-change处理程序记录下来。

目前,on-change处理程序对音频文件是有效的。 然而,之前的文件没有被加载,所以当组件加载时,文件的表单字段仍然是空的。我没有收到错误信息,因此目前很难解决这个问题。

从后台成功获取了文件(我可以加载之前的标题状态,而内容只是对于文件字段其不工作)。

export class EditStory extends Component {

  constructor(props) {
    super(props);
    this.getStory = this.getStory.bind(this);
    this.updateStory = this.updateStory.bind(this);
    this.onChangeTitle = this.onChangeTitle.bind(this);
    this.onChangeContent=this.onChangeContent.bind(this);
    this.onChangeAudio=this.onChangeAudio.bind(this);
    this.inputRef = React.createRef();


this.state = {
    story: {
        id: null,
        title: "",
        content: "",
        audio: ""
      }

    };
}


    componentDidMount() {
    this.getStory(this.props.match.params.id);
  }






  onChangeTitle(e) {
    const title = e.target.value;

    this.setState(prevState => ({
      story: {
        ...prevState.title,
        title: title
      }
    }), () => console.log(this.state));
  }


  onChangeContent(e) {
    const content = e.target.value;

    this.setState(prevState => ({
      story: {
        ...prevState.story,
        content: content
      }
    }), () => console.log(this.state));

  }


  onChangeAudio(e) {
    const audio = e.target.name;

    this.setState(prevState => ({
      story: {
        ...prevState.story,
        [e.target.name]: e.target.files[0]
      }
    }), () => console.log(this.state.audio));

  }



  getStory(id) {
    this.props.getSingleStory(id)
      .then(response => {
        this.setState({
          story: response.data
        });
        console.log(response.data);
        ;
      })
      .catch(e => {
        console.log(e);
      });
  }  



 updateStory() {
    const id = this.state.story.id;

    let title = this.state.story.title;

    let content = this.state.story.content;
    let audio = this.state.story.audio;
    let UpdatedData = new FormData();
    UpdatedData.append('audio', audio); // add audio to formData
    UpdatedData.append('title', title); // add title to formData
    UpdatedData.append('content', content);
    console.log (UpdatedData);
    this.props.editStory(
      id, 
      UpdatedData
    )
      .then(response => {
        console.log(response.data);

      })
      .catch(e => {
        console.log(e);
      });
  }





  static propTypes = {
      getSingleStory: PropTypes.func.isRequired,
      editStory: PropTypes.func.isRequired
  };


  render() {
    const {story} = this.state;
    return (
      <div>
        <h1>Edit {story.title}</h1>

          <div className="form-group">
            <label>Title</label>
            <input type="text" name="title" defaultValue={story.title} onChange={this.onChangeTitle} className="form-control" />
          </div>
          <div className="form-group">
            <label>Content</label>
            <textarea name="content" rows="5" defaultValue={story.content} onChange={this.onChangeContent} className="form-control" />
          </div>

          <div className="form-group">
            <label>Audio</label>
            <input
              className="form-control"
              type="file"
              name="audio"
              onChange={this.onChangeAudio}
              ref={this.inputRef} // refer to ref

            />
          </div>

          <div className="btn-group">
            <button type="submit" onClick={this.updateStory} className="btn btn-dark">Update</button>
            <button type="button"  className="btn btn-secondary">Cancel</button>
          </div>

      </div>
    );
  }
}


export default connect(
  null,
  { getSingleStory, editStory, }
)(EditStory);

可能是什么原因呢?

javascript reactjs
1个回答
1
投票

当你从服务器获取数据时,你可以通过在inputRef上设置文件键来动态设置输入字段的值。 然而,你需要将传入的文件转换为以下格式 FileList 使用 DataTransfer 构造函数。你可以在这篇文章中找到更多信息。如何在FileList对象上设置文件对象和长度属性,使文件也反映在FormData对象上?

你更新了代码。

getStory(id) {
    this.props.getSingleStory(id)
      .then(response => {
        this.setState({
          story: response.data
        });
        const file =  new File(response.data.file, "filename.txt, {
           type: "text/plain",
         });
        const dT = new ClipboardEvent('').clipboardData || new DataTransfer(); 
        dT.items.addfile(file);

        this.inputRef.current.files = dT.files;
        ;
      })
      .catch(e => {
        console.log(e);
      });
  }
© www.soinside.com 2019 - 2024. All rights reserved.