inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[리뉴얼] React로 NodeBird SNS 만들기

배포 전 Q&A

안녕하세요 개인 프로젝트를 하는데 같은 함수 호출이 여러번 됩니다.

해결된 질문

359

1ncursio

작성한 질문수 5

0

import React, useEffect, useState, useMemo, useCallback, useRef } from 'react';
import useSelector, useDispatch } from 'react-redux';
import Row, Col, Button, Form, Input, Typography, Modal, Avatar, Upload, message } from 'antd';
import useDropzone } from 'react-dropzone';
import ImgCrop from 'antd-img-crop';
import useInput from './hooks/useInput';
import CHANGE_PROFILE_REQUEST, CHANGE_NICKNAME_REQUEST, CHANGE_INTRO_REQUEST } from '../reducers/user';

const { Dragger } = Upload;
const { TextArea } = Input;
const { Text } = Typography;

const ProfileForm = () => {
  const {
    me,
    changeProfileLoading,
    changeNicknameLoading,
    changeNicknameDone,
    changeNicknameError,
    changeIntroLoading,
    changeIntroDone,
    changeIntroError,
  } = useSelector((state=> state.user);

  const [nickname, onChangeNickname] = useInput(me?.nickname || '');
  const [intro, onChangeIntro] = useInput(me?.introduction || '');
  const [profileImage, onChangeProfileImage, setProfileImage] = useInput();
  const dispatch = useDispatch();

  useEffect(() => {
    if (changeNicknameError) {
      Modal.error({
        content: '닉네임 변경 중에 오류가 발생했어요.',
      });
    }
  }, [changeNicknameError]);

  useEffect(() => {
    if (changeNicknameDone) {
      Modal.success({
        content: '닉네임을 변경했어요!',
      });
    }
  }, [changeNicknameDone]);

  useEffect(() => {
    if (changeIntroError) {
      Modal.error({
        content: '자기소개 변경 중에 오류가 발생했어요.',
      });
    }
  }, [changeIntroError]);

  useEffect(() => {
    if (changeIntroDone) {
      Modal.success({
        content: '자기소개를 변경했어요!',
      });
    }
  }, [changeIntroDone]);

  const beforeUpload = useCallback((file=> {
    console.log('beforeUpload');
    if (file.type !== 'image/jpg' && file.type !== 'image/jpeg' && file.type !== 'image/png') {
      message.error('jpg jpeg png 사진만 가능해요!');
      return false;
    }
    if (file.size > 2 * 1024 * 1024) {
      message.error('프로필 이미지는 2MB 이하만 가능해요!');
      return false;
    }
    setProfileImage(file);
    return true;
  });

  const onUpload = useCallback(
    (files=> {
      console.log('onUpload');
      if (!changeProfileLoading) {
        const imageFormData = new FormData();
        imageFormData.append('image', profileImage);
        console.log(profileImage);
        dispatch({
          type: CHANGE_PROFILE_REQUEST,
          data: imageFormData,
        });
      }
    },
    [profileImage, changeProfileLoading]
  );

  const onSubmitNickname = useCallback(() => {
    dispatch({
      type: CHANGE_NICKNAME_REQUEST,
      data: nickname,
    });
  }, [nickname]);

  const onSubmitChangeIntro = useCallback(() => {
    dispatch({
      type: CHANGE_INTRO_REQUEST,
      data: intro,
    });
  }, [intro]);

  const style = useMemo(() => ({ marginBottom: '20px', border: '1px solid #d9d9d9', padding: '20px' }), []);
  return (
    <Row justify="center">
      <Col xs={24} md={12}>
        <Form style={style} layout="vertical">
          <Form.Item style={{ textAlign: 'center' }}>
            <ImgCrop rotate quality="0.8" modalTitle="이미지 조정" modalOk="저장" modalCancel="취소">
              <Upload showUploadList={false} accept=".jpg,.jpeg,.png" onChange={onUpload} beforeUpload={beforeUpload}>
                <Avatar src={me?.profile ? `http://localhost:3100/${me?.profile}` : null} size={256}>
                  {me?.profile ? null : me?.nickname[0]}
                </Avatar>
              </Upload>
            </ImgCrop>
          </Form.Item>
          <Form.Item label={<Text strong>이메일</Text>}>
            <Text type="secondary">{me?.email}</Text>
          </Form.Item>
          <Form.Item label={<Text strong>닉네임</Text>}>
            <Input
              value={nickname}
              onChange={onChangeNickname}
              maxLength="20"
              suffix={<Text type="secondary">{` ${nickname.length} / 20`}</Text>}
            />
            <Button type="primary" onClick={onSubmitNickname} loading={changeNicknameLoading} disabled={me?.nickname === nickname}>
              변경
            </Button>
          </Form.Item>
          <Form.Item label={<Text strong>자기소개</Text>}>
            <TextArea
              placeholder="당신을 멋지게 소개해보세요!"
              value={intro}
              onChange={onChangeIntro}
              rows="5"
              spellCheck={false}
              style={{ resize: 'none' }}
              showCount
              maxLength="500"
            />
          </Form.Item>
          <Form.Item style={{ textAlign: 'center' }}>
            <Button
              type="primary"
              shape="round"
              size="large"
              onClick={onSubmitChangeIntro}
              loading={changeIntroLoading}
              disabled={me?.introduction === intro}
              style={{
                width: 200,
              }}
            >
              저장
            </Button>
          </Form.Item>
        </Form>
      </Col>
    </Row>
  );
};

export default ProfileForm;

강의를 듣고 나서 개인 프로젝트를 만드는 중인데, antd의 Upload 컴포넌트를 이용해서 이미지 업로드를 구현했습니다. 그런데 이미지를 업로드하면 onUpload 함수가 3번 실행됩니다. beforeUpload는 1번만 실행되는데, onUpload 만 3번 실행이 됩니다. 오늘 하루종일 찾아봤는데 문제점을 모르겠습니다. 혹시 어디가 문제일까요?

redux react nodejs express Next.js

답변 1

0

1ncursio

바로 해결했네요 onUpload에서 처리하지않고 그냥 beforeUpload에서 처리했습니당

넥스트 버젼 질문

0

77

2

로그인시 401 Unauthorized 오류가 뜹니다

0

89

1

무한 스크롤 중 스크롤 튐 현상

0

174

1

특정 페이지 접근을 막고 싶을 때

0

103

2

createGlobalStyle의 위치와 영향범위

0

96

2

인라인 스타일 리렌더링 관련

0

90

2

vsc 에서 npm init 설치시 오류

0

146

2

nextjs 15버전 사용 가능할까요?

0

158

1

화면 새로고침 문의

0

121

1

RTK에서 draft, state 차이가 있나요?

0

153

2

Next 14 사용해도 될까요?

0

452

1

next, node 버전 / 폴더 구조 질문 드립니다.

0

349

1

url 오류 질문있습니다

0

211

1

ssh xxxxx로 우분투에 들어가려니까 port 22: Connection timed out

0

372

1

sudo certbot --nginx 에러

0

1272

2

Minified React error 콘솔에러 (hydrate)

0

469

1

카카오 공유했을 때 이전에 작성했던 글이 나오는 버그

0

246

1

프론트서버 배포 후 EADDRINUSE에러 발생

0

325

1

npm run build 에러

0

518

1

front 서버 npm run build 중에 발생한 에러들

0

381

1

서버 실행하고 브라우저로 들어갔을때 404에러

0

337

2

css 서버사이드 랜더링이 적용되지 않아서 문의 드립니다.

0

286

1

팔로워 3명씩 불러오고 데이터 합쳐주는걸로 바꾸고 서버요청을 무한으로하고있습니다.

0

237

2

해시태그 검색에서 throttle에 관해 질문있습니다.

0

201

1