单击一个div,打开文件浏览器

ary*_*yan 12 reactjs

我的反应成分:

import React, { PropTypes, Component } from 'react'


class Content extends Component {
    handleClick(e) {
        console.log("Hellooww world")
    }
    render() {
        return (
            <div className="body-content">
                <div className="add-media" onClick={this.handleClick.bind(this)}>
                    <i className="plus icon"></i>
                    <input type="file" id="file" style={{display: "none"}}/>
                </div>
            </div>
        )
    }
}

export default Content
Run Code Online (Sandbox Code Playgroud)

在这里,当我点击带图标的div时,我想打开一个<input>文件,显示我选择照片的选项.选择照片后,我想获取选择照片的值.我怎么能这样做?

小智 27

将ref属性添加到您的输入:

<input type="file" id="file" ref="fileUploader" style={{display: "none"}}/>
Run Code Online (Sandbox Code Playgroud)

更改handleClick函数:

handleClick(e) {
    this.refs.fileUploader.click();
}
Run Code Online (Sandbox Code Playgroud)

由于您使用的是ES6,因此需要将其绑定到handleClick函数,我们可以在构造函数中执行此操作:

constructor (props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}
Run Code Online (Sandbox Code Playgroud)

  • 这只是打开对话框。 (2认同)

Tia*_*vêa 15

其他只是将输入放在您的视图上,您​​将需要处理输入内容的更改.为此,实现onChange,并获取打开的文件信息,如下所示:

<input id="myInput"
   type="file"
   ref={(ref) => this.upload = ref}
   style={{display: 'none'}}
   onChange={this.onChangeFile.bind(this)}
/>

<RaisedButton
    label="Open File"
    primary={false}
    onClick={()=>{this.upload.click()}}
/>


onChangeFile(event) {
    event.stopPropagation();
    event.preventDefault();
    var file = event.target.files[0];
    console.log(file);
    this.setState({file}); /// if you want to upload latter
}
Run Code Online (Sandbox Code Playgroud)

控制台将输出:

File {
  name: "my-super-excel-file.vcs", 
  lastModified: 1503267699000, 
  lastModifiedDate: Sun Aug 20 2017 19:21:39 GMT-0300 (-03), 
  webkitRelativePath: "", 
  size: 54170,
  type:"application/vnd.vcs"
}
Run Code Online (Sandbox Code Playgroud)

现在你可以像你想的那样使用它.但是,如果你想上传它,你必须从:

var form = new FormData();
form.append('file', this.state.file);

YourAjaxLib.doUpload('/yourEndpoint/',form).then(result=> console.log(result));
Run Code Online (Sandbox Code Playgroud)


Ang*_*gel 10

使用React Hooks上传新答案

首先创建您的Input ref hook

const inputFile = useRef(null) 
Run Code Online (Sandbox Code Playgroud)

然后将其设置为INPUT并添加要显示的样式:没有输入将不会显示在屏幕上

<input type='file' id='file' ref={inputFile} style={{display: 'none'}}/>
Run Code Online (Sandbox Code Playgroud)

然后创建用于处理打开文件的函数,该函数应位于与useRef Hook相同的函数内

 const onButtonClick = () => {
    // `current` points to the mounted file input element
   inputFile.current.click();
  };
Run Code Online (Sandbox Code Playgroud)

然后将函数设置为Button元素

 <button onClick={onButtonClick}>Open file upload window</button>
Run Code Online (Sandbox Code Playgroud)

HTML输入文件的API


leo*_*idv 9

使用React.createRef()方法,React 16.3提供了更好的方法.请参阅https://reactjs.org/blog/2018/03/29/react-v-16-3.html#createref-api

打字稿示例:

export class MainMenu extends React.Component<MainMenuProps, {}> {

private readonly inputOpenFileRef : RefObject<HTMLInputElement>

constructor() {
    super({})

    this.inputOpenFileRef = React.createRef()
}

showOpenFileDlg = () => {
    this.inputOpenFileRef.current.click()
}

render() {

    return (
       <div>
                <input ref={this.inputOpenFileRef} type="file" style={{display:"none"}}/>
                <button onClick={this.showOpenFileDlg}>Open</Button>
      </div>
    )
}
}
Run Code Online (Sandbox Code Playgroud)


Niy*_*abo 7

所有建议的答案都很棒。我超越了允许用户添加图像并立即预览它。我使用了 React hooks。

感谢大家的支持

结果应如下所示

在此输入图像描述

import React, { useEffect, useRef, useState } from 'react';

// Specify camera icon to replace button text 
import camera from '../../../assets/images/camera.svg'; // replace it with your path

// Specify your default image
import defaultUser from '../../../assets/images/defaultUser.svg'; // replace it with your path

// Profile upload helper

const HandleImageUpload = () => {
  // we are referencing the file input
  const imageRef = useRef();

  // Specify the default image
  const [defaultUserImage, setDefaultUserImage] = useState(defaultUser);
  
  // On each file selection update the default image
  const [selectedFile, setSelectedFile] = useState();

  // On click on camera icon open the dialog
  const showOpenFileDialog = () => {
    imageRef.current.click();
  };

  // On each change let user have access to a selected file
  const handleChange = (event) => {
    const file = event.target.files[0];
    setSelectedFile(file);
  };

  // Clean up the selection to avoid memory leak
  useEffect(() => {
    if (selectedFile) {
      const objectURL = URL.createObjectURL(selectedFile);
      setDefaultUserImage(objectURL);
      return () => URL.revokeObjectURL(objectURL);
    }
  }, [selectedFile]);

  return {
    imageRef,
    defaultUserImage,
    showOpenFileDialog,
    handleChange,
  };
};

// Image component
export const ItemImage = (props) => {
  const {itemImage, itemImageAlt} = props;
  return (
    <>
      <img
        src={itemImage}
        alt={itemImageAlt}
        className="item-image"
      />
    </>
  );
};

// Button with icon component
export const CommonClickButtonIcon = (props) => {
  const {
    onHandleSubmitForm, iconImageValue, altImg,
  } = props;
  return (
    <div className="common-button">
      <button
        type="button"
        onClick={onHandleSubmitForm}
        className="button-image"
      >
        <img
          src={iconImageValue}
          alt={altImg}
          className="image-button-img"
        />
      </button>
    </div>
  );
};

export const MainProfileForm = () => {
  const {
    defaultUserImage,
    handleChange,
    imageRef,
    showOpenFileDialog,
  } = HandleImageUpload();

  return (
    <div className="edit-profile-container">

      <div className="edit-profile-image">
        <ItemImage
          itemImage={defaultUserImage}
          itemImageAlt="user profile picture"
        />
        <CommonClickButtonIcon // Notice I omitted the text instead used icon
          onHandleSubmitForm={showOpenFileDialog}
          iconImageValue={camera}
          altImg="Upload image icon"
        />
        <input
          ref={imageRef}
          type="file"
          style={{ display: 'none' }}
          accept="image/*"
          onChange={handleChange}
        />
      </div>
    </div>
  );
};


Run Code Online (Sandbox Code Playgroud)

我的CSS

.edit-profile-container {
  position: relative;
}

.edit-profile-container .edit-profile-image {
  position: relative;
  width: 200px;
  display: flex;
  justify-content: center;
}

.edit-profile-container .edit-profile-image .item-image {
  height: 160px;
  width: 160px;
  border-radius: 360px;
}

.edit-profile-container .edit-profile-image .common-button {
  position: absolute;
  right: 0;
  top: 30px;
}

.edit-profile-container .edit-profile-image .common-button .button-image {
  outline: none;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
}

.edit-profile-container .edit-profile-image .common-button .image-button-img {
  height: 30px;
  width: 30px;
  box-shadow: 0 10px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
}

Run Code Online (Sandbox Code Playgroud)


Max*_*wer 5

您可以将其包裹在标签中,当您单击标签时,它会单击对话框。

    <div>
      <label htmlFor="fileUpload">
        <div>
          <h3>Open</h3>
          <p>Other stuff in here</p>
        </div>
      </label>
      <input hidden id="fileUpload" type="file" accept="video/*" />
    </div>
Run Code Online (Sandbox Code Playgroud)