LoginSignup
0
0

Semantic UI ReactのInputでファイルアップロードをしたいけど、ref経由でクリックできない

Posted at

経緯

Semantic UI ReactのInputを使ってファイルアップロードを実装したら、なんかダサい、、

import { Input } from "semantic-ui-react";

const Component = () => <Input type='file' />

export default Component;

 ↓↓↓ こうなる
image.png

じゃあ、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;

ボタンを押してみたが、エラー、、
image.png
"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;
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0