我想自定义输入标签以上传文件。 这是我的代码。在这里,对于htmlFor属性,我给出了输入标签的ID,然后就可以了。但是我想使用useRef ref。我怎样才能做到这一点 ?如果我遵循以下方法,则多次渲染此组件会出现问题。对吗?
const App = () => {
const inputRef = useRef(null);
const [file, setFile] = useState(null);
return (
<>
<input
ref={inputRef}
accept=".pdf"
style={{ display: "none" }}
id="raised-button-file"
multiple
type="file"
onChange={e => {
setFile(e.target.files[0]);
}}
/>
<label htmlFor="raised-button-file">
<button component="span">
<span>file</span>
</button>
</label>
</>
);
};
答案 0 :(得分:0)
使用<label>
标签的另一种方法是将元素包装为子元素,而无需为其指定id
。
<label>
<input
accept=".pdf"
style={{ display: "none" }}
multiple
type="file"
onChange={e => {
setFile(e.target.files[0]);
}}
/>
<span>File</span>
</label>
如果您希望使用自己的引用打开文件输入对话框,则可以这样做。
const handleOpenFileInput = () => {
inputRef.current.click();
};
<label onClick={handleOpenFileInput}>
<button>file</button>
</label>
<input
ref={inputRef}
accept=".pdf"
style={{ display: "none" }}
multiple
type="file"
onChange={e => {
setFile(e.target.files[0]);
}}
/>
答案 1 :(得分:0)
如果您使用userRef
,将无法解决您的问题。问题出在label
和htmlFor
属性中。它不断获取其ID与htmlFor
属性匹配的输入,并且由于多次渲染该组件,因此始终会得到第一个匹配项。
我只需将每个组件的id
作为属性传递,以便每次标签与正确的输入匹配时。我将代码更改为如下所示:
const Form = ({id}) => {
const onChangeInput = e => {
const [file] = e.target.files
}
return (
<form>
<div>
<input type="file" id={id} name="file" className="my-input" accept="application/pdf" style={{display:"none"}} onChange={onChangeInput} multiple/>
<label htmlFor={id}>Upload</label>
</div>
</form>
)
}
function App() {
return (
<div className="App">
<Form id="form1"/>
<Form id="form2"/>
<Form id="form3"/>
</div>
);
}
为确保每个文档均已正确上传,我将className
属性传递给输入,以便可以获取所有输入。运行这段代码,我找到了我上传的所有文件
Array.from(document.querySelectorAll('.my-input')).map(v => v.files[0].name)