web-dev-qa-db-ja.com

ReactJSファイル入力をリセットする方法

ファイルアップロードの入力があります。

<input onChange={this.getFile} id="fileUpload" type="file" className="upload"/>

そして、私はこの方法でアップロードを処理します:

getFile(e) {
    e.preventDefault();
    let reader = new FileReader();
    let file = e.target.files[0];
    reader.onloadend = (theFile) => {
        var data = {
            blob: theFile.target.result, name: file.name,
            visitorId:  this.props.socketio.visitorId
        };
        console.log(this.props.socketio);
        this.props.socketio.emit('file-upload', data);
    };
    reader.readAsDataURL(file);
}

同じファイルを2回アップロードすると、アップロードイベントは発生しません。どうすれば修正できますか?単純なjsコードの場合、次のことを行うだけで十分です。this.value = null;変更ハンドラー。 ReactJSでどのようにできますか?

22

次のように入力値をクリアできると思います。

e.target.value = null;

ファイル入力を制御することはできません。Reactを行う特定の方法はありません。

41
Freez

これは私のために働いています-ref = {ref => this.fileInput = ref}

<input id="file_input_file" type="file" onChange={(e) => this._handleFileChange(e)} ref={ref=> this.fileInput = ref} />

私の場合、ファイルがサーバーにアップロードされたら、次のステートメントを使用してクリアします

 this.fileInput.value = "";
24
Jozcar

私のために働いたのは、ファイル入力にkey属性を設定し、それをリセットする必要があるときにキー属性値を更新することでした:

functionThatResetsTheFileInput() {
  let randomString = Math.random().toString(36);

  this.setState({
    theInputKey: randomString
  });
}

render() {
  return(
    <div>
      <input type="file"
             key={this.state.theInputKey || '' } />
      <button onClick={this.functionThatResetsTheFileInput()} />
    </div>
  )
}

それはReact=に入力を最初から再びレンダリングさせる。

18
tonatiuhnb

ファイル入力内でkeyを更新することでそれを行います。これにより、再レンダリングが強制され、以前に選択されたファイルはなくなります。

_<input type="file" key={this.state.inputKey} />
_

状態inputKeyを変更すると、コンポーネントが再レンダリングされます。 inputKeyを変更する1つの方法は、フィールドをクリアすることになっているボタンのクリック時に常にDate.now()に設定することです。

8
aelor

組み込みファイルの入力値をまったく使用しないことがわかっている場合は、これをinput要素に含めることもできます。

<input value={""} ... />

このように、値はレンダリング時に常に空の文字列にリセットされ、onChange関数に不当に含める必要はありません。

2
IRTrapGod

ファイル入力は常に制御されていないことは知っていますが、次のコードは自分の目的で動作します。問題なく入力をリセットできます。

constructor(props) {
    super(props);
    this.state = {
        selectedFile: undefined,
        selectedFileName: undefined,
        imageSrc: undefined,
        value: ''
    };

    this.handleChange = this.handleChange.bind(this);
    this.removeImage = this.removeImage.bind(this);
}

handleChange(event) {
    if (event.target.files[0]) {
        this.setState({
            selectedFile: event.target.files[0],
            selectedFileName: event.target.files[0].name,
            imageSrc: window.URL.createObjectURL(event.target.files[0]),
            value: event.target.value,
        });
    }
}

// Call this function to reset input
removeImage() {
    this.setState({
        selectedFile: undefined,
        selectedFileName: undefined,
        imageSrc: undefined,
        value: ''
    })
}

render() {
    return (
        <input type="file" value={this.state.value} onChange={this.handleChange} />
    );
}
1
Jack L.

ここにreduxフォームを使用した私のソリューションがあります

class FileInput extends React.Component {
  constructor() {
    super();

    this.deleteImage = this.deleteImage.bind(this);
  }

  deleteImage() {
    // Just setting input ref value to null did not work well with redux form
    // At the same time just calling on change with nothing didn't do the trick
    // just using onChange does the change in redux form but if you try selecting
    // the same image again it doesn't show in the preview cause the onChange of the
    // input is not called since for the input the value is not changing
    // but for redux form would be.

    this.fileInput.value = null;
    this.props.input.onChange();
  }

  render() {
    const { input: { onChange, value }, accept, disabled, error } = this.props;
    const { edited } = this.state;

    return (
      <div className="file-input-expanded">
        {/* ref and on change are key properties here */}
        <input
          className="hidden"
          type="file"
          onChange={e => onChange(e.target.files[0])}
          multiple={false}
          accept={accept}
          capture
          ref={(input) => { this.fileInput = input; }}
          disabled={disabled}
        />
        {!value ?
          {/* Add button */}
          <Button
            className="btn-link action"
            type="button"
            text="Add Image"
            onPress={() => this.fileInput.click()}
            disabled={disabled}
          />
          :
          <div className="file-input-container">
            <div className="flex-row">
              {/* Image preview */}
              <img src={window.URL.createObjectURL(value)} alt="outbound MMS" />
              <div className="flex-col mg-l-20">
                {/* This button does de replacing */}
                <Button
                  type="button"
                  className="btn-link mg-b-10"
                  text="Change Image"
                  onPress={() => this.fileInput.click()}
                  disabled={disabled}
                />
                {/* This button is the one that does de deleting */}
                <Button
                  type="button"
                  className="btn-link delete"
                  text="Delete Image"
                  onPress={this.deleteImage}
                  disabled={disabled}
                />
              </div>
            </div>
            {error &&
              <div className="error-message"> {error}</div>
            }
          </div>
        }
      </div>
    );
  }
}

FileInput.propTypes = {
  input: object.isRequired,
  accept: string,
  disabled: bool,
  error: string
};

FileInput.defaultProps = {
  accept: '*',
};

export default FileInput;
0
Agustina Chaer

クリックonClickごとに入力をリセットできるため、同じファイルonChangeでもトリガーされます。

<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
0
Elnoor

ReactはJavaScriptに過ぎず、ReactコードでもDOM操作を使用できます。これは動作するはずです

document.getElementsByClassName('upload')[0].value = null;
0
Rastko Sasic