Javascript 如何通过另一个DOM触发输入文件事件
我有一个输入按钮和输入文件,我想点击按钮,它会在REACT JS中触发输入文件事件 然后按下按钮Javascript 如何通过另一个DOM触发输入文件事件,javascript,reactjs,Javascript,Reactjs,我有一个输入按钮和输入文件,我想点击按钮,它会在REACT JS中触发输入文件事件 然后按下按钮 React.createElement('a',{onClick: this.doClick},'Select File') 那么,当我们单击A HREF时,如何定义和触发输入文件单击事件呢 谢谢你的帮助。 :-编辑:这是我很久以前回答的一个问题,我不知道现在有多少反应。有趣的是,它被认为是有效的 因此,对于阅读此答案的任何人;这个答案是错误的,这是一个很好的例子,说明了你不应该在react中做的
React.createElement('a',{onClick: this.doClick},'Select File')
那么,当我们单击A HREF时,如何定义和触发输入文件单击事件呢
谢谢你的帮助。
:-编辑:这是我很久以前回答的一个问题,我不知道现在有多少反应。有趣的是,它被认为是有效的
因此,对于阅读此答案的任何人;这个答案是错误的,这是一个很好的例子,说明了你不应该在react中做的事情
请在下面找到一个很好的反模式,同样,不要这样做
=================================================
您可以使用jQuery实现这一点:
this.doClick: function() {
$('input[type=file]').trigger('click');
}
React不提供触发事件的特定函数,您可以使用jQuery或简单地使用本机Javascript:请参阅MDN上的事件。您不需要jQuery来实现此目的。您甚至不需要事件处理程序。HTML对此有一个特定的元素,称为 首先,确保输入元素具有id属性:
React.createElement('input',{type:'file', name:'myfile', id:'myfile'})
然后,而不是:
React.createElement('a',{onClick: this.doClick},'Select File')
尝试:
另一种解决方案是将输入元素作为标签的子元素,而不是添加htmlFor和id属性
现在单击标签应该触发与单击输入本身相同的行为。您可以使用ref,f.e: 在类组件上:
<input
ref={fileInput => this.fileInput = fileInput}
type="file"
/>
<button onClick={this.triggerInputFile}> Select File </button>
在功能组件中使用useRef钩子。需要^16.8
const Dummy = () => {
const inputFileRef = useRef( null );
const onFilechange = ( e ) => {
/*Selected files data can be collected here.*/
console.log( e.target.files );
}
const onBtnClick = () => {
/*Collecting node-element and performing click*/
inputFileRef.current.click();
}
return (
<form className="some-container">
<input
type="file"
ref={inputFileRef}
onChange={onFileChange}
/>
<button onClick={onBtnClick}>Select file</button>
</form>
)
}
使用React.createRef类实现,并使用节点元素处理单击
使用挂钩:
基于@YÒGÎ的答案,下面是一个使用TypeScript的实现:
class Dummy extends React.Component {
fileInputRef: React.RefObject<HTMLInputElement> = React.createRef();
forwardClickToInputElement = () => {
this.fileInputRef.current!.click();
};
handleUploadDemand = (ie: ChangeEvent<HTMLInputElement>) => {
const fileList: FileList = ie.target.files;
// do something with the FileList, for example:
const fileReader = new FileReader();
fileReader.onload = () => {
const str = String(fileReader.result);
try {
const parsedContent = YOUR_OWN_PARSING(str);
} catch (error) {
// YOUR OWN ERROR HANDLING
}
};
fileReader.readAsBinaryString(fileList[0])
}
render() {
return (
<div className="some-container">
<button onClick={this.forwardClickToInputElement}>Select File</button>
<input ref={this.fileInputRef} type="file" onChange={this.handleSelectFile} hidden={true}/>
</div>
)
}
}
参考资料:
如何在React with Typescript中使用引用的解决方案
使用ref类型窄化运算符
React.createElement'input',{type:'file',name:'myfile'}然后点击React.createElement'a',{onClick:this.doClick},'Select file',那么当我们点击a HREF时如何定义和触发输入文件点击事件呢?是的,目前我总是这样做,但我需要的是找到通过React触发的方法,不是jQuery使用React的原因是为了避开jQuery。这个答案很糟糕。jQuery完全提供了对DOM的控制,而react则相反。强烈建议不要将它们一起使用。谢谢好心的先生!这是正确的方法,应该是一个公认的答案。那么如何将上传的文件保存在状态变量中呢?我在输入中添加了一个onChange,但它不起作用??在输入标记中使用onChange属性处理它。e、 target.files[0]}/>如何确保已填充ref?它不会触发渲染,因此在函数组件中,ref的第一个渲染始终为null。每次重新渲染只是为了抓取ref实例是否被认为是最佳实践?null只是为了标识为引用初始值。安装组件后,将为参考对象指定其当前元素。在我们的用例中,可以在componentDidMount之后执行输入操作。因此,无论是否使用任何初始值,都是安全的。来自userefsource:请记住,useRef的内容更改时不会通知您。更改.current属性不会导致重新渲染。
triggerInputFile = () => this.fileInput.click()
const Dummy = () => {
const inputFileRef = useRef( null );
const onFilechange = ( e ) => {
/*Selected files data can be collected here.*/
console.log( e.target.files );
}
const onBtnClick = () => {
/*Collecting node-element and performing click*/
inputFileRef.current.click();
}
return (
<form className="some-container">
<input
type="file"
ref={inputFileRef}
onChange={onFileChange}
/>
<button onClick={onBtnClick}>Select file</button>
</form>
)
}
class Dummy extends React.Component {
constructor( props ) {
super( props );
this.inputFileRef = React.createRef();
this.onFileChange = this.handleFileChange.bind( this );
this.onBtnClick = this.handleBtnClick.bind( this );
}
handleFileChange( e ) {
/*Selected files data can be collected here.*/
console.log( e.target.files );
}
handleBtnClick() {
/*Collecting node-element and performing click*/
this.inputFileRef.current.click();
}
render() {
return (
<form className="some-container">
<input
type="file"
ref={this.inputFileRef}
onChange={this.onFileChange}
/>
<button onClick={this.onBtnClick}>Select file</button>
</form>
)
}
}
import React, {useRef} from 'react';
const FancyInput = () => {
const fileInput = useRef(null)
const handleClick = () => {
fileInput.current.click()
}
const handleFileChange = event => {
console.log("Make something")
}
return(
<div className="patientactions-container">
<input
type="file"
onChange={(e) => handleFileChange(e)}
ref={fileInput}
/>
<div onClick={() => handleClick()}></div>
</div>
)
}
export default FancyInput;
class Dummy extends React.Component {
fileInputRef: React.RefObject<HTMLInputElement> = React.createRef();
forwardClickToInputElement = () => {
this.fileInputRef.current!.click();
};
handleUploadDemand = (ie: ChangeEvent<HTMLInputElement>) => {
const fileList: FileList = ie.target.files;
// do something with the FileList, for example:
const fileReader = new FileReader();
fileReader.onload = () => {
const str = String(fileReader.result);
try {
const parsedContent = YOUR_OWN_PARSING(str);
} catch (error) {
// YOUR OWN ERROR HANDLING
}
};
fileReader.readAsBinaryString(fileList[0])
}
render() {
return (
<div className="some-container">
<button onClick={this.forwardClickToInputElement}>Select File</button>
<input ref={this.fileInputRef} type="file" onChange={this.handleSelectFile} hidden={true}/>
</div>
)
}
}