ファイルのアップロードを実装しようとしていますが、 [〜#〜] suir [〜#〜]<Input>
、ボタン、ラベルなどを使用しています。
これは厳密に、レンダリングでの要素の使用についてです。
通常のhtml <label>
および<input>
要素を使用すると、このプロセスは期待どおりに機能します。
<Form.Field>
<label>File input & upload for dataschemas & datasources</label>
<input type="file" onChange={this.fileChange} />
<Button type="submit">Upload</Button>
</Form.Field>
今、私は、SUIR <Input>
要素と、<Button>
要素を持ついくつかの小道具をスタイリングに使用しようとしています。
<Form.Field>
<label>File input & upload </label>
<Input type="file" onChange={this.fileChange}>
<Button
content="Choose File"
labelPosition="left"
icon="file"
/>
</Input>
<Button type="submit">Upload</Button>
</Form.Field>
Codesandbox here にアクセスして、私が話していることをより視覚的に理解することができます。
SUIRの実装例でChoose File
をクリックしても、通常のhtml <input>
の場合と異なり、ユーザーにシステムからファイルを選択するように求めるプロンプトが表示されません。同じように動作するようにセマンティックで<Input type="file ...>
を取得する方法がわかりません。
SUIRはそのままではFileInputボタンソリューションを提供しません。しかし、そのようなボタンの独自の実装を簡単に作成できます。たとえば、これは通常、hidden
ファイル入力と、ユーザーがクリックしたときに非表示の入力クリックをトリガーするボタンを使用して行われます。
_ <Button
content="Choose File"
labelPosition="left"
icon="file"
onClick={() => this.fileInputRef.current.click()}
/>
<input
ref={this.fileInputRef}
type="file"
hidden
onChange={this.fileChange}
/>
_
ここで、_this.fileInputRef
_はReact React.createRef()
メソッドによって作成された参照です。これは、上記のソリューションで確認できます codesandbox example です。
GProstの答えは完璧に機能します。別のケースでは、このファイル入力ボタンを実現するためにref
を作成したくない場合があります。
以下のソリューションはhtmlFor
プロパティを使用し、そのid
を<input>
に渡します。 refを使用しないと、余分なJSがなくなり、ボタンと入力の間の不要な通信がなくなります。
<Button as="label" htmlFor="file" type="button">
Some button stuff
</Button>
<input type="file" id="file" style={{ display: "hidden" }} onChange={this.onChange} />
以下のようにreactでファイルアップロードフォームを設定できます。
また、この例で示されているように、ファイル名とファイルの参照を取得できます。express, node
スタックを使用している場合は、axios
とフロントエンドアップロードロジックとバックエンドコードを含めました
class Thingy extends React.Component {
uploadFile = event => {
// filename
console.log('filename ' + event.target.value);
//file
console.log('file ' + event.target.files[0]);
// if you are using axios then you can use below code
//const formData = new FormData();
// formData.append('file', event.target.files[0])
// axios.put(
// 'url',
// formData,
// { headers: { 'content-type': 'multipart/form-data' } }
// ).then(data => {
// console.log('file uploaded')
// console.log(data)
// }).catch(e => {
// console.log('error')
// console.log(e)
// })
// in express , node, backend code would be
//import formidable from 'formidable'
//(req, res) => {
// let form = new formidable.IncomingForm();
// form.parse(req, (err, fields, files) => {
// you can get the file from files.file.path
// })
// }
}
render() {
console.log("rendered");
return (
<div>
<input type="file" id="file" name="filename" onChange={this.uploadFile} />
</div>
);
}
}
// Render it
ReactDOM.render(
<Thingy/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>