web-dev-qa-db-ja.com

React Material UIの簡単な入力でファイルのアップロードを有効にする方法は?

私は、redux form&material uiを備えたelectron-react-boilerplateを使用してファイルをアップロードする簡単なフォームを作成しています。

問題は、マテリアルUIがアップロードファイル入力をサポートしていないため、入力ファイルフィールドの作成方法がわからないことです。

これを達成する方法についてのアイデアはありますか?

31
gintoki27

入力をコンポーネントでラップし、containerElementプロパティにvalue 'label'...

<RaisedButton
   containerElement='label' // <-- Just add me!
   label='My Label'>
   <input type="file" />
</RaisedButton>

詳しくは、このGitHub issue をご覧ください。

編集:2019を更新します。

@ galki の一番下の答えを確認してください

TLDR;

<input
  accept="image/*"
  className={classes.input}
  style={{ display: 'none' }}
  id="raised-button-file"
  multiple
  type="file"
/>
<label htmlFor="raised-button-file">
  <Button variant="raised" component="span" className={classes.button}>
    Upload
  </Button>
</label> 
27
vblazenka

新しいMUIバージョン:

<input
  accept="image/*"
  className={classes.input}
  style={{ display: 'none' }}
  id="raised-button-file"
  multiple
  type="file"
/>
<label htmlFor="raised-button-file">
  <Button variant="raised" component="span" className={classes.button}>
    Upload
  </Button>
</label> 
40
galki

@galkiのソリューションよりも構造的に意味のある別の> = v1.0ソリューション。

RaisedButtonは、v1.0以降では非推奨です。 containerElement(ドキュメント化されていない可能性がありますか?)に関する詳細情報は見つかりませんが、現在のAPIはこの目的のためにcomponentを提供しています。

<Button
  variant="contained"
  component="label"
>
  Upload File
  <input
    type="file"
    style={{ display: "none" }}
  />
</Button>
19
elijahcarrel

次に、v3.9.2を使用してIconButtonを使用して入力をキャプチャする(写真/ビデオキャプチャ)例を示します。

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';

import { withStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import PhotoCamera from '@material-ui/icons/PhotoCamera';
import Videocam from '@material-ui/icons/Videocam';

const styles = (theme) => ({
    input: {
        display: 'none'
    }
});

class MediaCapture extends Component {
    static propTypes = {
        classes: PropTypes.object.isRequired
    };

    state: {
        images: [],
        videos: []
    };

    handleCapture = ({ target }) => {
        const fileReader = new FileReader();
        const name = target.accept.includes('image') ? 'images' : 'videos';

        fileReader.readAsDataURL(target.files[0]);
        fileReader.onload = (e) => {
            this.setState((prevState) => ({
                [name]: [...prevState[name], e.target.result]
            }));
        };
    };

    render() {
        const { classes } = this.props;

        return (
            <Fragment>
                <input
                    accept="image/*"
                    className={classes.input}
                    id="icon-button-photo"
                    onChange={this.handleCapture}
                    type="file"
                />
                <label htmlFor="icon-button-photo">
                    <IconButton color="primary" component="span">
                        <PhotoCamera />
                    </IconButton>
                </label>

                <input
                    accept="video/*"
                    capture="camcorder"
                    className={classes.input}
                    id="icon-button-video"
                    onChange={this.handleCapture}
                    type="file"
                />
                <label htmlFor="icon-button-video">
                    <IconButton color="primary" component="span">
                        <Videocam />
                    </IconButton>
                </label>
            </Fragment>
        );
    }
}

export default withStyles(styles, { withTheme: true })(MediaCapture);
3
Markus Hay