最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - Why is my fileRef not opening the element I'm referencing onClick - Stack Overflow

programmeradmin2浏览0评论

I want to upload a file by clicking the image element.

I have an Input element of file type with a useRef. I'm referencing the useRef in the img Onclick but it's not opening the file selector.

I tested it by clicking the input file type directly and it works, but it won't work when I'm referencing it from the img element.

I need to be able to open the file navigator by clicking the image that's referencing the Input, not the Input of file type

import { useContext, useEffect, useState, useRef } from "react";
import {
  Box,
  Button,
  Card,
  FormControl,
  Input,
  TextField,
  Typography,
} from "@mui/material";
import profilePlaceholder from "../../assets/images/imagePH.png";
import { signOut } from "firebase/auth";
import { auth } from "../../environments/environment";
import { EditProfileModal } from "./EditProfileModal";
import useGetUserProfile from "../../hooks/useGetUserProfile";
import { UserProfileContext } from "../../Context/UserProfileContext";
import useUploadImage from "../../hooks/useUploadImage";

export const ProfileForm = () => {
  const [showLogin, setShowLogin] = useState(false);
  const { userProfile, setUserProfile } = useGetUserProfile();
  const {userProfileContext, setUserProfileContext} = useContext(UserProfileContext)
  const { handleImageUpload } = useUploadImage();
  const fileRef = useRef<HTMLInputElement>(null);
  
  useEffect(() => {
    if (userProfile) {
      setUserProfileContext(userProfile);
    }
  }, [userProfile, setUserProfile, setUserProfileContext]);

  return (
    <>
      <form noValidate>
        <Box display="flex" justifyContent="flex-end" p={2}>
          <Button
            variant="contained"
            color="secondary"
            onClick={async () => {
              await signOut(auth);
              window.location.href = "/login";
            }}
            sx={{
              borderRadius: "50%",
              width: 80,
              height: 80,
            }}>
            <span role="img" aria-label="logout">
              Logout
            </span>
          </Button>
        </Box>
        <Box mt={0} display="flex" justifyContent="center">
          <img
            src={profilePlaceholder}
            alt="Profile Placeholder"
            style={{ maxWidth: "100%", height: "auto" }}
            onClick={() => {
              fileRef.current?.click();
              console.log("click");
            }}
          />
          <Input
          type='file'
          ref={fileRef}
          style={{ display: "none" }}
          />
          <Box sx={{ flexDirection: "column" }}>
            <Typography
              ml={2}
              fontSize={{ base: "sm", md: "lg" }}
              color="white"
              sx={{ fontSize: "2rem" }}>
              {userProfileContext?.username || ""}
            </Typography>
            <Button
              variant="contained"
              size="small"
              onClick={() => setShowLogin(true)}
              sx={{ marginTop: 2, background: "white", color: "black" }}>
              Edit Profile
            </Button>
          </Box>
        </Box>
      </form>
      <EditProfileModal show={showLogin} close={() => setShowLogin(false)} />
    </>
  );

I want to upload a file by clicking the image element.

I have an Input element of file type with a useRef. I'm referencing the useRef in the img Onclick but it's not opening the file selector.

I tested it by clicking the input file type directly and it works, but it won't work when I'm referencing it from the img element.

I need to be able to open the file navigator by clicking the image that's referencing the Input, not the Input of file type

import { useContext, useEffect, useState, useRef } from "react";
import {
  Box,
  Button,
  Card,
  FormControl,
  Input,
  TextField,
  Typography,
} from "@mui/material";
import profilePlaceholder from "../../assets/images/imagePH.png";
import { signOut } from "firebase/auth";
import { auth } from "../../environments/environment";
import { EditProfileModal } from "./EditProfileModal";
import useGetUserProfile from "../../hooks/useGetUserProfile";
import { UserProfileContext } from "../../Context/UserProfileContext";
import useUploadImage from "../../hooks/useUploadImage";

export const ProfileForm = () => {
  const [showLogin, setShowLogin] = useState(false);
  const { userProfile, setUserProfile } = useGetUserProfile();
  const {userProfileContext, setUserProfileContext} = useContext(UserProfileContext)
  const { handleImageUpload } = useUploadImage();
  const fileRef = useRef<HTMLInputElement>(null);
  
  useEffect(() => {
    if (userProfile) {
      setUserProfileContext(userProfile);
    }
  }, [userProfile, setUserProfile, setUserProfileContext]);

  return (
    <>
      <form noValidate>
        <Box display="flex" justifyContent="flex-end" p={2}>
          <Button
            variant="contained"
            color="secondary"
            onClick={async () => {
              await signOut(auth);
              window.location.href = "/login";
            }}
            sx={{
              borderRadius: "50%",
              width: 80,
              height: 80,
            }}>
            <span role="img" aria-label="logout">
              Logout
            </span>
          </Button>
        </Box>
        <Box mt={0} display="flex" justifyContent="center">
          <img
            src={profilePlaceholder}
            alt="Profile Placeholder"
            style={{ maxWidth: "100%", height: "auto" }}
            onClick={() => {
              fileRef.current?.click();
              console.log("click");
            }}
          />
          <Input
          type='file'
          ref={fileRef}
          style={{ display: "none" }}
          />
          <Box sx={{ flexDirection: "column" }}>
            <Typography
              ml={2}
              fontSize={{ base: "sm", md: "lg" }}
              color="white"
              sx={{ fontSize: "2rem" }}>
              {userProfileContext?.username || ""}
            </Typography>
            <Button
              variant="contained"
              size="small"
              onClick={() => setShowLogin(true)}
              sx={{ marginTop: 2, background: "white", color: "black" }}>
              Edit Profile
            </Button>
          </Box>
        </Box>
      </form>
      <EditProfileModal show={showLogin} close={() => setShowLogin(false)} />
    </>
  );
Share Improve this question edited Feb 17 at 4:40 Drew Reese 203k17 gold badges237 silver badges268 bronze badges asked Feb 16 at 23:02 D.HodgesD.Hodges 2,0974 gold badges26 silver badges58 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

According to the docs, ref is passed to the Root element (div) so you need to use inputRef prop to pass ref directly to the input element.

You need to change this:

<Input
  type='file'
  ref={fileRef}
  style={{ display: "none" }}
/>

To this:

<Input
  type='file'
  inputRef={fileRef}
  style={{ display: "none" }}
/>
发布评论

评论列表(0)

  1. 暂无评论