ファイルアップロードの入力があります。
<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でどのようにできますか?
次のように入力値をクリアできると思います。
e.target.value = null;
ファイル入力を制御することはできません。Reactを行う特定の方法はありません。
これは私のために働いています-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 = "";
私のために働いたのは、ファイル入力に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=に入力を最初から再びレンダリングさせる。
ファイル入力内でkey
を更新することでそれを行います。これにより、再レンダリングが強制され、以前に選択されたファイルはなくなります。
_<input type="file" key={this.state.inputKey} />
_
状態inputKey
を変更すると、コンポーネントが再レンダリングされます。 inputKey
を変更する1つの方法は、フィールドをクリアすることになっているボタンのクリック時に常にDate.now()
に設定することです。
組み込みファイルの入力値をまったく使用しないことがわかっている場合は、これをinput要素に含めることもできます。
<input value={""} ... />
このように、値はレンダリング時に常に空の文字列にリセットされ、onChange関数に不当に含める必要はありません。
ファイル入力は常に制御されていないことは知っていますが、次のコードは自分の目的で動作します。問題なく入力をリセットできます。
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} />
);
}
ここに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;
クリックonClick
ごとに入力をリセットできるため、同じファイルonChange
でもトリガーされます。
<input onChange={this.onChange} onClick={e => (e.target.value = null)} type="file" />
ReactはJavaScriptに過ぎず、ReactコードでもDOM操作を使用できます。これは動作するはずです
document.getElementsByClassName('upload')[0].value = null;