javascript - 在 React 中创建自定义输入类型文件按钮

标签 javascript html reactjs css ecmascript-6

我正在尝试创建自定义 <input type="file">在 React 中,上传按钮在上传后在按钮本身上可见上传文件的名称。我正在创建它作为组件。我发现创建一个 codepen 演示非常困难,所以我只是在这里上传代码(抱歉)。

import React, { Component, PropTypes } from 'react';
import './InputFile.css';

export default class InputFile extends Component {

constructor(props: any)
{
    super(props);
    this.getUploadedFileName = this.getUploadedFileName.bind(this);
}

getUploadedFileName(selectorFiles: FileList, props) {

const { id } = this.props;

;( function ( document, window, index )
{
    var inputs = document.querySelectorAll(`#${id}`);
    Array.prototype.forEach.call( inputs, function( input )
    {
        var label    = input.nextElementSibling,
            labelVal = label.innerHTML;

        input.addEventListener( 'change', function( e )
        {
            var fileName = '';
            if( this.files && this.files.length > 1 )
                fileName = ( this.getAttribute( 'data-multiple-caption' ) || 
'' ).replace( '{count}', this.files.length );
            else
                fileName = e.target.value.split( '\\' ).pop();

            if( fileName )
                label.querySelector( 'span' ).innerHTML = fileName;
            else
                label.innerHTML = labelVal;
        });

        // Firefox bug fix
        input.addEventListener( 'focus', function(){ input.classList.add( 
'has-focus' ); });
        input.addEventListener( 'blur', function(){ input.classList.remove( 
'has-focus' ); });
    });
}( document, window, 0 ));
}


render () {

    const { id, text, multiple } = this.props;

    return(
        <div>
            <input id={id} type="file" className="km-btn-file" data-multiple-caption="{count} files selected" multiple={multiple} onChange={ (e, id) => this.getUploadedFileName(e.target.files, id)}></input>
            <label htmlFor={id} className="km-button km-button--primary km-btn-file-label">
                <span>{text}</span>
            </label>
        </div>
    );
}
}

InputFile.propTypes = {
    id: PropTypes.string.isRequired,
    text: PropTypes.string.isRequired,
    multiple: PropTypes.string,
};

我正在我的其他文件中导入此组件 <InputFile id={'input-file'} text={'Upload File'} multiple={'multiple'}/>

这是CSS代码

.km-button--primary {
    background-color: #5C5AA7;
    color: #FFFFFF;
}
.km-button {
    border-radius: 3px;
    -webkit-appearance: none;
    border: none;
    outline: none;
    background: transparent;
    height: 36px;
    padding: 0px 16px;
    margin: 0;
    font-size: 14px;
    font-weight: 400;
    text-align: center;
    min-width: 70px;
    transition: all 0.3s ease-out;
}
.km-btn-file {
    width: 0.1px;
      height: 0.1px;
      opacity: 0;
      overflow: hidden;
      position: absolute;
      z-index: -1;
  }
  .km-btn-file-label {
    line-height: 36px;
    cursor: pointer;
  }

我面临的问题是,当我第一次单击按钮并选择要上传的文件时,它会选择文件但不会使用文件名更新文本“上传文件”。但是在第二次点击它之后它工作正常。我不知道为什么会这样,为此我需要帮助。

谢谢。

最佳答案

您可以使用组件“state”来更新您的元素。

constructor(props: any)
{
  super(props);
  this.state = {message:'some initial message'};
}

对于 onChange 事件做:

getUploadedFileName = (e) => {
   let files = e.target.files,
       value = e.target.value,
       message;
   if( files && files.length > 1 ) message = `${files.length} files selected`;
   else                            message = value.split( '\\' ).pop();

   if(message) this.setState({...this.state,message});
}

然后在元素中将值绑定(bind)到状态:

<div>
   <input id={id} type="file" className="km-btn-file" 
      data-multiple-caption={this.state.message}
      multiple={multiple} 
      onChange={this.getUploadedFileName}>
   </input>
   <label htmlFor={id} className="km-button km-button--primary km-btn-file-label">
       <span>{text}</span>
   </label>
</div>

关于javascript - 在 React 中创建自定义输入类型文件按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49555806/

相关文章:

javascript - 加载共享库时出错 : libgtk-3. so.0: 无法打开共享对象文件: 没有这样的文件或目录

javascript - 尝试将 Canvas 从一页复制到另一页

php - 如何在此代码 php 上通过 Mysqli 搜索限制分页?

reactjs - 如何在 JSX 中使用转义字符

javascript - 使用 javascript 和 html 创建程序时遇到问题

javascript - 查询为给定事件类型注册的事件监听器列表

javascript - 请问我该如何处理这个错误 "Unhandled Rejection (Type Error): Cannot read property ' 未定义的过滤器”

javascript - Angular 2 : why no empty element tags?

javascript - 在 React 中切换值后重新激活它

javascript - 如何取消react中的setTimeout时间