TIL_230227

그래도 해야지·2023년 2월 27일
0

TIL

목록 보기
39/44

문제
'{ setIsModalOpen: Dispatch; }' 형식은 'IntrinsicAttributes' 형식에 할당할 수 없습니다.
'IntrinsicAttributes' 형식에 'setIsModalOpen' 속성이 없습니다.ts(2322)

원인
부모 컴포넌트(MyProfile.tsx)에서 타입으로 props를 받는 자식 컴포넌트(MyProfileEditModal.tsx)에서도 부모컴포넌트에 넘겨줄 때 타입을 지정을 해주지 않아서 생긴 문제

사실 부모랑 자식이랑??헷갈림???
모달이 부모고 마이프로필이 자식같은뎅??
=> 한번 물어보기

해결

// MyProfile.tsx
  
 type Props = {
  children: React.ReactNode;
};

const MyProfile = ({ children }: Props) => {
  return
  }
// MyProfileEditModal.tsx
  
const MyProfileEditModal = ({ setIsModalOpen }: any) => {
  return 
  }

======================고치다 만거 ㅠㅠ

import MyProfile from '../../components/MyPage/MyProfile/MyProfile';
import { useState } from 'react';
import { Dispatch } from 'react';

interface Props {
  setIsModalOpen: Dispatch<any>;
}
const MyPage: any = ({ setIsModalOpen }: Props) => {
  // const [isModalOpen, setIsModalOpen] = useState<any>(false);
  return (
    <>
      <MyProfile />
    </>
  );
};

export default MyPage;
  
import { useState } from 'react';
import * as S from './style';
import MyPageTab from '../MyPageTab/MyPageTab';
import DeleteAccount from '../../Authentication/DeleteAccount/DeleteAccount';
import MyProfileEditModal from './MyProfileEditModal';
import { useRecoilValue } from 'recoil';
import { userInfo } from '../../../atoms';
import { Dispatch } from 'react';
import basicProfileImg from '../../../assets/Img/basicProfileImg.png';

interface Props {
  setIsModalOpen: Dispatch<any>;
}

const MyProfile = () => {
  // 휴대전화, 성별, 생일
  const user = useRecoilValue(userInfo);
  const userInfos = user.userInfomation;
  console.log('userInfos', userInfos);

  // 프로필 수정 모달창
  const [isModalOpen, setIsModalOpen] = useState<any>(false);

  return (
    <S.MyPageAll>
      <S.MyPageContainer>
        {isModalOpen && <MyProfileEditModal setIsModalOpen={setIsModalOpen} />}
        <S.MyProfileBox>
          <S.EmailInputWrpper>
            <S.EmailText>이메일</S.EmailText>
            <S.EmailInputDiv>{userInfos.email}</S.EmailInputDiv>
          </S.EmailInputWrpper>
          <S.PhoneNumInputWrpper>
            <S.PhoneNumText>휴대전화</S.PhoneNumText>
            <S.PhoneNumInputDiv>{userInfos.phoneNumber}</S.PhoneNumInputDiv>
          </S.PhoneNumInputWrpper>
          <S.GenderInputWrpper>
            <S.GenderText>성별</S.GenderText>
            <S.GenderInputDiv>{userInfos.gender}</S.GenderInputDiv>
          </S.GenderInputWrpper>
          <S.AgeInputWrpper>
            <S.AgeText>생일</S.AgeText>
            <S.AgeInputDiv>{userInfos.age}</S.AgeInputDiv>
          </S.AgeInputWrpper>
          <button onClick={() => setIsModalOpen(true)}>회원정보 수정</button>
          <DeleteAccount />
        </S.MyProfileBox>
      </S.MyPageContainer>
      <MyPageTab />
    </S.MyPageAll>
  );
};

export default MyProfile;
  import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Modal from '@mui/material/Modal';
import { useEffect, useState } from 'react';
import { auth, storage } from '../../../services/firebase';
import { updateProfile } from 'firebase/auth';
import { getDownloadURL, ref, uploadString } from 'firebase/storage';
import { v4 as uuidv4 } from 'uuid';
import * as S from './style';
import UpdatePassword from '../../Authentication/UpdatePassword/UpdatePassword';
import { useRecoilState, useRecoilValue } from 'recoil';
import { editModal } from '../../../atoms';
import { profileState } from '../../../atoms';

const MyProfileEditModal = ({ setIsModalOpen }: any) => {
  const [profileUrl, setProfileUrl] = useRecoilState(profileState);

  // 모달 관련
  const [open, setOpen] = useRecoilState(editModal);
  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  // 닉네임 관련
  const currentUserInfos = auth.currentUser; // 현재 로그인한 사용자의 정보들(파이어베이스)
  const [nickname, setNickname] = useState<any>(''); // 현재 닉네임 상태변경
  const [currentUser, setCurrentUser] = useState<any>(''); // 현재 로그인한 사용자 가져오기 및 변경 전 데이터

  // 이미지 관련
  const imgProfileUrl = useRecoilValue(profileState);
  const [imgFile, setImgFile] = useState<any>(imgProfileUrl); // 이미지 파일 엄청 긴 이름
  const [imgFileName, setImgFileName] = useState<any>(''); // 이미지 파일 이름.jpg
  const [imgUploadUrl, setImgUploadUrl] = useState<any>('');

  // 현재 로그인한 사용자 가져오기
  useEffect(() => {
    auth.onAuthStateChanged((user) => {
      if (user) {
        setCurrentUser(currentUserInfos);
      } else {
        return console.log('로그인 안됨');
      }
    });
  }, [currentUser]);

  // 변경할 닉네임 받아오는 함수
  // 변경눌렀을 때 마이페이지 업뎃되면 닉네임은 끝난거
  const ToChangeNicknameInput = (event: any) => {
    setNickname(event.target.value);
  };

  // 수정완료 버튼 누를 때 유효성 검사 확인만
  const nicknameChangeOnClick = async (e: any) => {
    if (nickname.length < 2 || nickname.length > 5) {
      alert('2글자 이상 5글자 이하로 입력해주세요.');
      return;
    } else if (imgFile.length === 0) {
      setImgUploadUrl(
        'https://firebasestorage.googleapis.com/v0/b/popcorn1-4b47e.appspot.com/o/basic_profile.png?alt=media&token=d58d0f49-79bd-400a-a4ae-ceca444734ae',
      );
    } else if (imgFile.length !== 0) {
      const imgRef = ref(storage, `profileUploadImg/${imgFileName + uuidv4()}`);
      const response = await uploadString(imgRef, imgFile, 'data_url');
      const downloadImageUrl = await getDownloadURL(response.ref);
      setImgUploadUrl(downloadImageUrl);
      setProfileUrl(downloadImageUrl);
    }

    await updateProfile(currentUser, {
      displayName: nickname,
      photoURL: imgUploadUrl,
    })
      .then(() => {
        setNickname(nickname);
        alert('프로필 수정 완료!');
        setOpen(false);
      })
      .catch((error: any) => {
        error;
      });
  };

  // 모달키면 이미지가 보이는데 유저가 클릭하면 업데이트
  const saveNewProfileImg = (event: any) => {
    const target = event.currentTarget;
    const theFile = (target.files as FileList)[0]; // 이미지 인풋창에서 클릭하면 이미지
    setImgFile(theFile.name);
    const reader = new FileReader();
    reader.readAsDataURL(theFile);
    reader.onloadend = (finishedEvent: any) => {
      setImgFile(finishedEvent.currentTarget.result);
    };
  };

  return (
    <div>
      <Button
        onClick={handleOpen}
        style={{
          width: '33%;',
          height: '40px',
        }}
      >
        <S.EditModalBtnText>회원정보수정</S.EditModalBtnText>
      </Button>
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
      >
        <S.EditModalAll>
          <Box sx={style}>
            <S.EditModalTitleText>회원정보 수정</S.EditModalTitleText>
            <S.EditModalImgLabelInputWrapper>
              <S.EditModalProfileImgLabel htmlFor="modalProfileUploadImg">
                {imgFile && <S.EditModalProfileImgShow src={imgFile} />}
              </S.EditModalProfileImgLabel>
              <S.EditModalProfileImgInput
                type="file"
                accept="image/*"
                id="modalProfileUploadImg"
                onChange={saveNewProfileImg}
                style={{ display: 'none' }}
              />
            </S.EditModalImgLabelInputWrapper>
            <S.EditModalNicknameInputWrapper>
              <S.EditModalNicknameText>닉네임</S.EditModalNicknameText>
              <S.EditModalNicknameInput
                type="text"
                placeholder={'닉네임을 입력해주세요'}
                onChange={ToChangeNicknameInput}
                value={nickname}
              />
            </S.EditModalNicknameInputWrapper>
            <S.EditModalEmailInputWrpper>
              <S.EditModalEmailText>이메일(아이디)</S.EditModalEmailText>
              <S.EditModalEmailInput
                placeholder={currentUser?.email}
                readOnly
              />
            </S.EditModalEmailInputWrpper>
            <UpdatePassword />
            <S.EditModalBtnWrapper>
              <S.EditModalCanceleButton onClick={handleClose}>
                취소
              </S.EditModalCanceleButton>

              <S.EditModalCompleteButton
                onClick={nicknameChangeOnClick}
                type="submit"
              >
                수정완료
              </S.EditModalCompleteButton>
            </S.EditModalBtnWrapper>
          </Box>
        </S.EditModalAll>
      </Modal>
    </div>
  );
};
export default MyProfileEditModal;

const style = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
  width: '30%',
  height: '800px',
  bgcolor: 'background.paper',
  border: '2px solid transparent',
  boxShadow: 24,
  p: 4,
};

0개의 댓글