経緯
Semantic UI ReactのInputを使ってファイルアップロードを実装したら、なんかダサい、、
import { Input } from "semantic-ui-react";
const Component = () => <Input type='file' />
export default Component;
じゃあ、Inputは非表示にして、Buttonクリックしたらref経由でinputクリックしてファイル選択できるようにしよう
import { useRef } from "react";
import { Button, Input } from "semantic-ui-react";
const Component = () => {
const ref = useRef(null);
const handleClick = () => {
ref.current.click();
};
return (
<>
<Button onClick={handleClick}>ファイルを選択</Button>
<Input type='file' ref={ref} style={{ display: 'none' }} />
</>
);
}
export default Component;
ボタンを押してみたが、エラー、、
"ref.current.click is not a function"なんて言われちゃいました
環境
名前 | バージョン |
---|---|
react | 18.2.0 |
semantic-ui-react | 2.1.4 |
調査1. ref.current.clickが本当に関数ではないのかを調べる
参考にしたサイトでは使えていたので、参考と同じように、inputタグを使用してrefを使ってみる
import { useRef } from "react";
import { Button, Input } from "semantic-ui-react";
const Component = () => {
const ref = useRef(null);
const handleClick = () => {
ref.current.click();
}
return (
<>
<Button onClick={handleClick}>ファイルを選択</Button>
{/* <Input type='file' ref={ref} style={{ display: 'none' }} /> */}
<input type='file' ref={ref} style={{ display: 'none' }} />
</>
)
}
export default Component;
→問題なく動いたので、Inputのrefからではclickが実行できないよう
解決策1. Inputではなく、内部のinputに直接refを渡す
この記事でやったことを応用
import { useRef } from "react";
import { Button, Input } from "semantic-ui-react";
const Component = () => {
const ref = useRef(null);
const handleClick = () => {
ref.current.click();
}
return (
<>
<Button onClick={handleClick}>ファイルを選択</Button>
<Input type='file' style={{ display: 'none' }}>
<input ref={ref} />
</Input>
</>
)
}
export default Component;
解決策2. HTMLのforとidの紐づけを利用する
import { Input, Label } from "semantic-ui-react";
const Component = () => {
return (
<>
<Label as='label' htmlFor='file-upload'>ファイルを選択</Label>
<Input type='file' style={{ display: 'none' }} id='file-upload' />
</>
)
}
export default Component;
解決策3. 非表示なのでInputではなく、inputを使用する
import { useRef } from "react";
import { Button } from "semantic-ui-react";
const Component = () => {
const ref = useRef(null);
const handleClick = () => {
ref.current.click();
}
return (
<>
<Button onClick={handleClick}>ファイルを選択</Button>
<input type='file' ref={ref} style={{ display: 'none' }} />
</>
)
}
export default Component;