web-dev-qa-db-ja.com

React-入力タイプファイルセマンティックUI React

ファイルのアップロードを実装しようとしていますが、 [〜#〜] 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 ...>を取得する方法がわかりません。

10
DJ2

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 です。

17
GProst

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} />
6
DJ2

以下のように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>
3
NuOne