如何在 React 的 Material UI 简单输入上启用文件上传?

IT技术 reactjs electron react-redux redux-form formsy-material-ui
2021-04-11 11:02:53

我正在创建一个简单的表单来使用具有 redux 表单和材料 ui 的电子react样板上传文件。

问题是我不知道如何创建输入文件字段,因为材料 ui 不支持上传文件输入。

关于如何实现这一目标的任何想法?

6个回答

APIcomponent为此目的而提供

<Button
  variant="contained"
  component="label"
>
  Upload File
  <input
    type="file"
    hidden
  />
</Button>

较新的 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> 
谢谢,这是来自此处的示例,您还需要input: {display: 'none'} 为此元素添加样式
2021-05-29 11:02:53
您好 - 一旦文件上传(即当您突出显示文件并在弹出的表单上单击打开时)onChange,将<input />调用上的事件,但我的文件target在事件对象属性(或上的任何属性)中不可用我可以看到的事件对象)。该文件在哪里可用?
2021-06-01 11:02:53
要不就 <input hidden>
2021-06-03 11:02:53
@jboxxx:文件将打开target.filesinput元素有一个内置files属性,列出每个选定的文件)
2021-06-03 11:02:53
在最新版本variant="raised"中已弃用,它期望 ["text","outlined","contained"] 之一
2021-06-18 11:02:53

你需要用 组件,并添加值为 'label' 的containerElement属性...

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

您可以在此 GitHub问题 中阅读有关它的更多信息

编辑:更新 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> 
如果您在 2019 年访问此内容,请查看底部 @galki 的答案:D
2021-05-28 11:02:53
但是如何使用这个文件对象?HTML FileReader 似乎不起作用:/考虑到,我用过<input type='file' onChange='handleFile'> handleFile = file => { .. }
2021-05-31 11:02:53

这是一个使用 IconButton 使用 v3.9.2 捕获输入(照片/视频捕获)的示例:

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);
IconButton 绝对需要 component="span" ,这就是我所缺少的!
2021-06-17 11:02:53

这对我有用(“@material-ui/core”:“^4.3.1”):

    <Fragment>
        <input
          color="primary"
          accept="image/*"
          type="file"
          onChange={onChange}
          id="icon-button-file"
          style={{ display: 'none', }}
        />
        <label htmlFor="icon-button-file">
          <Button
            variant="contained"
            component="span"
            className={classes.button}
            size="large"
            color="primary"
          >
            <ImageIcon className={classes.extendedIcon} />
          </Button>
        </label>
      </Fragment>