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

Javascript 在React中创建自定义输入类型文件按钮,javascript,html,reactjs,css,ecmascript-6,Javascript,Html,Reactjs,Css,Ecmascript 6,我正在尝试创建自定义的上传按钮,上传后,在按钮上可以看到上传文件的名称。我创建这个组件。我发现创建codepen演示非常困难,所以我只是在这里上传代码(很抱歉) 我面临的问题是,当我第一次单击按钮并选择要上载的文件时,它会选择该文件,但不会用文件名更新文本“upload file”。但在第二次点击后,它工作正常。我不知道为什么会这样,为此我需要帮助 谢谢。您需要将文本属性从props绑定到您的状态,因此在构造函数中您必须这样做 this.state = {...props}; 或 然后在您想要

我正在尝试创建自定义的
上传按钮,上传后,在按钮上可以看到上传文件的名称。我创建这个组件。我发现创建codepen演示非常困难,所以我只是在这里上传代码(很抱歉)

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


谢谢。

您需要将文本属性从props绑定到您的状态,因此在构造函数中您必须这样做

this.state = {...props};

然后在您想要更新视图值时调用,而不是自己手动设置标签上的innerHtml; this.setState({text:new value})

在你的渲染方法中

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

当您调用this.setState时,它会告诉React重新呈现您的组件,然后该组件将从状态中获取更新的值。

您可以使用组件“状态”更新元素

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});
}
然后在元素中,将值绑定到状态:

<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>

{text}

您应该使用您的生命周期和状态,以便它直接更新。它仍以相同的方式运行。你必须选择文件两次,使“文本”更新。我认为这是伟大的工作。不过,我想最后一部分的
{text}
应该是
{this.state.message}
。除非我遗漏了什么。
constructor(props: any)
{
  super(props);
  this.state = {message:'some initial message'};
}
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});
}
<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>