강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

밈몀묘님의 프로필 이미지
밈몀묘

작성한 질문수

React 완벽 마스터: 기초 개념부터 린캔버스 프로젝트까지

등록구현, 공통 컴포넌트, dayjs 라이브러리

axios post 사용할때 페이지 새로고침 문제

작성

·

170

·

수정됨

0

Home.jsx

이렇게 하고

 

import { useEffect, useState } from 'react';
import HomeDataLength from '../components/HomeDataLength.jsx';
import HomeSearch from '../components/HomeSearch.jsx';
import CanvasItemList from '../components/CanvasItemList.jsx';
import SearchBar from '../components/SearchBar.jsx';
import GridFlexBTN from '../components/GridFlexBTN.jsx';
import { deleteHome, createHome, getHome } from '../api/home.js';
import { v4 as uuid } from 'uuid';
import dayjs from 'dayjs';

export default function Home() {
  const [isGrid, setIsGrid] = useState(true);
  const [search, setSearch] = useState('');
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(false);

  useEffect(() => {
    const api = async () => {
      setIsLoading(true);
      setError(false);
      try {
        const response = await getHome('');
        setData(response.data);
      } catch (err) {
        setError(err);
      } finally {
        setIsLoading(false);
      }
    };
    api();
  }, []);

  const [isLoadingCreate, setIsLoadingCreate] = useState(false);
  const [createError, setCreateError] = useState(false);
  // 등록버튼 누르면 새로운 데이터 저장
  const handleNewCreate = async () => {
    // setIsLoadingCreate(true);
    // setCreateError(false);
    // try {
    const id = uuid();
    const newCreate = {
      id,
      date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      text: `${id.substring(0, 4)}-테스트`,
      category: '테스트',
    };
    await createHome(newCreate);
    console.log(123);

    // const res = await getHome();
    // setData(res.data);
    // } catch (err) {
    // setCreateError(err);
    // console.log(createError, 'createError');
    // } finally {
    // setIsLoadingCreate(false);
    // }
  };

  const handleText = text => {
    const searchData = data.filter(d =>
      d.text.toLowerCase().includes(text.toLowerCase()),
    );
    if (searchData.length === 0) {
      setSearch(null);
    } else {
      setSearch(searchData);
    }
  };

  const handleDelete = async id => {
    // const newData = data.filter(d => d.id !== id);
    // setData(newData);
    await deleteHome(id);
  };

  return (
    <>
      <>
        <div className="flex flex-col md:flex-row justify-between items-center">
          <button
            className="hover:bg-blue-400 bg-blue-500 text-white rounded-md text-bold p-3"
            onClick={handleNewCreate}
          >
            등록하기
          </button>
          {isLoadingCreate && <p>등록중</p>}
          {createError && <p>{createError}</p>}
          <SearchBar handleText={handleText} />
          <GridFlexBTN setIsGrid={setIsGrid} isGrid={isGrid} />
        </div>

        <HomeDataLength data={data} error={error} isLoading={isLoading} />
        <HomeSearch search={search} />

        {!isLoading && !error && (
          <CanvasItemList
            data={data || []}
            search={search}
            isGrid={isGrid}
            handleDelete={handleDelete}
          />
        )}
      </>
    </>
  );
}

home.js 파일은 아래와 같은 상태이면

 

import { home } from './http';

// 목록 조회
export const getHome = () => {
  return home.get('/');
};

// 등록
export const createHome = newCreate => {
  try {
    console.log('ㅅㅣ작');
  } catch (error) {
    console.log('에러');
  } finally {
    console.log('종료');
  }
  // debugger;
  return home.post('/', newCreate);
};

// 수정

// 삭제
export const deleteHome = id => {
  return home.post('/', id);
};

db는 server-json을 사용하고 있습니다.

그런데 get 요청을 할때는 잘 작동하는데

post로 등록하거나 삭제할때는 db에 정상 등록, 삭제되는데 화면이 새로고침이 되버리는 상태입니다. Home.jsx 화면이 리렌더링이 되도록 하고싶은데 새로고침은 왜 그런지 모르겠습니다.

 

postman으로도 post로 db에 저장했는데 리액트 화면이 자동으로 새로고침 되버립니다. 구글링도 해봤는데 해결이 안되서 문의드립니다.

혹시나 해서 db.json이 변경되면 화면도 변경될까 싶어서 을 db.json --watch로만 해보고 --watch도 없애봤는데 안됩니다.

 

 

  const handleNewCreate = async () => {
    console.log('시작1');

    const id = uuid();
    const newCreate = {
      id,
      date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      text: `${id.substring(0, 4)}-테스트`,
      category: '테스트',
    };
    const data = await createHome(newCreate);
    console.log(data, 'data');
    console.log('시작2');
    debugger;
 
  };

debugger를 사용했을때

image.png

이렇게 데이터 나오는데 디버거 끄는 순간 바로 화면이 새로고침 되고 있습니다. 그리고 콘솔창도 새창으로 이전 내역이 다 사라지는 상태입니다.

 

답변 2

0

짐코딩님의 프로필 이미지
짐코딩
지식공유자

이 문제는 아마도 폼 제출(form submission) 기본 동작과 관련이 있는 것 같습니다. React에서 axios로 POST 요청을 보낼 때 페이지가 새로고침되는 현상은 일반적으로 다음과 같은 원인이 있을 수 있습니다.

문제 원인

  1. 버튼이 <form> 태그 내부에 있을 경우, 기본적으로 submit 동작을 수행합니다.

  2. axios.post()가 실행된 후에도 기본 이벤트가 계속 진행되어 페이지가 새로고침될 수 있습니다.

해결 방법

handleNewCreate 함수에 이벤트 객체를 매개변수로 받아 기본 동작을 방지하는 코드를 추가하세요:

const handleNewCreate = async (e) => {
  // 이벤트의 기본 동작 방지
  if (e) e.preventDefault();
  
  const id = uuid();
  const newCreate = {
    id,
    date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    text: `${id.substring(0, 4)}-테스트`,
    category: '테스트',
  };
  
  // POST 요청 후 데이터 갱신
  try {
    await createHome(newCreate);
    // 성공 후 데이터 다시 불러오기
    const response = await getHome();
    setData(response.data);
  } catch (error) {
    console.error("오류 발생:", error);
  }
};

그리고 버튼 onClick 핸들러에서 이벤트 객체를 전달하세요:

<button
  className="hover:bg-blue-400 bg-blue-500 text-white rounded-md text-bold p-3"
  onClick={(e) => handleNewCreate(e)}
>
  등록하기
</button>

또한 createHome 함수가 Promise를 제대로 반환하는지 확인하세요:

export const createHome = (newCreate) => {
  try {
    console.log('시작');
    return home.post('/', newCreate); // Promise 반환
  } catch (error) {
    console.log('에러');
    throw error; // 에러 전파
  }
};


0

짐코딩님의 프로필 이미지
짐코딩
지식공유자

안녕하세요 🙂

소스코드를 디버깅 해봐야 할 것 같은데요!

깃헙주소 혹은 제 메일주소로 소스코드를 공유해 주실 수 있으실까요?

(메일로 공유시 node_modules 디렉토리 제거 후 압축 후 공유해주시면 감사드리겠습니다.)

메일주소 확인

밈몀묘님의 프로필 이미지
밈몀묘

작성한 질문수

질문하기