인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

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

김가을님의 프로필 이미지

작성한 질문수

실무 중심! FE 입문자를 위한 React

13-2. Recoil의 Selector로 API 연동

jotai로 변경했을 때 코드

작성

·

293

0

Recoil과 비슷해 보이는 Jotai로 혼자 바꿔보고 있는 중입니다 ㅠㅠ 근데 이번 강의 코드는 어떻게 바꿔야 하는지 감이 안 와요....

답변 3

1

more j님의 프로필 이미지

아하 네네 이후 강의들어보시면 받아오는 주소를 따로 빼게되거든요 저는 최종코드라 좀 다르긴한데 우선 공유드릴게요 !

surveyState.js

import { atom } from 'jotai';

import getSurvey from '../../../survices/getSurvey';

const surveyState = atom(async (get) => {
  const res = await getSurvey(window.location.pathname.split('/')[2]);
  return res.data;
});

export default surveyState;

getSurvey.js

import mainApi from './apis/mainApi';
function getSurvey(surveyId) {
  return mainApi.get(`/surveys/${surveyId}`);
}
export default getSurvey;

mainApi.js

import axios from 'axios';

const mainApi = axios.create({
  baseURL: 'http://localhost:3001',
});

export default mainApi;

 

추가적으로 제가 헤맸던부분은 questionLengthState.js

인데 이건 atomWithQuery 얘 설치하셔야돼요 !

강의 내용엔 제가 작성한 코드처럼 api를 직접 호출하지않고

import해서 사용하는데 이상하게 그렇게 하면 오류가 나서 저는 직접호출했어요 !

import { atomWithQuery } from 'jotai-tanstack-query';

import getSurvey from '../../../survices/getSurvey';
const questionLengthState = atomWithQuery(() => ({
  queryKey: ['surveyData'],
  queryFn: async () => {
    try {
      const res = await getSurvey(window.location.pathname.split('/')[2]); // API 직접 호출
      return res.data?.questions?.length ?? 0; // 방어 코드 추가 (questions가 없을 경우 0 반환)
    } catch (error) {
      console.error('❌ 설문 데이터를 가져오는 중 오류 발생:', error);
      return 0; //  오류 발생 시 기본값 0 반환
    }
  },
  suspense: true, // Suspense 활성화하여 로딩 상태 자동 처리
}));

export default questionLengthState;

해보시고 모르시겠는거 알려주시면 또 공유드릴게요 ~!

김가을님의 프로필 이미지
김가을
질문자

답변 감사합니다 계속해서 강의 들어보고 공유해 주신 코드 참고하겠습니다 공유해 주셔서 감사합니다!

김가을님의 프로필 이미지
김가을
질문자

async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding 'use client' to a module that was originally written for the server.

 

이런 오류는 안 나오셨나요?

more j님의 프로필 이미지

혹시 컴포넌트에서 async/await를 바로 호출하셨나요 ?? 저는 저런오류는 나지않았습니다 !

김가을님의 프로필 이미지
김가을
질문자

surveyState.js를 생성하고 이걸

useCurrentQuestion.js에서 호출하여 사용하는 것이 아닐까요?

 

useCurrentQuestion.js 코드입니다... ㅠㅠ

import { useAtomValue } from 'jotai';

import surveyState from '../stores/survey/surveyState';
import useStep from './useStep';

function useCurrentQuestion() {
  const step = useStep();
  const surveyData = useAtomValue(surveyState);
  const question = surveyData?.questions || [];

  return question[step];
}

export default useCurrentQuestion;
more j님의 프로필 이미지

아하 추후에 변경되는 부분이있어서 surveyState.js

value로 읽어오지 않았습니다

하단의 코드로 useCurrentQuestion.js수정해주세요 !

import { useAtom } from 'jotai';
const [serveyData] = useAtom(surveyState);

 

완성된 코드도 같ㅇ이 드릴게요

 

import { useAtom } from 'jotai';

//import { useEffect } from 'react';
import surveyState from '../components/stores/survey/surveyState';
import useStep from './useStep';
//mport useServeyId from './useSurveyId';
function useCurrentQuestion() {
  const step = useStep(); // 스텝과정을 커스텀훅으로 만들어서 가져왔음
  // const questions = useAtomValue(surveyState).questions; //조타이를 사용해서 공통으로 사용되는 값들을 atom에 옮겼고요 그걸 가져왔어요,
  //그리고 이걸 hook으로 만들었습니다.
  //const surveyId = useServeyId();
  //const [serveyData, setServeyData] = useAtom(surveyState);
  const [serveyData] = useAtom(surveyState);
  const questions = serveyData?.questions || []; //초기엔 serveyData여기가 빈배열일것임 그래서 빈배열을 셋팅해주고 아래의 api에서 값을 셋팅해준이후엔 화면에 그려지게됨

  /* useEffect(() => {
    // 1.퀘스쳔박스에서 내려줄데이터를 여기 hook에서 관장하고있기 때문에 이쪽에서api를 호출해줌
    2. 그러나 store에서 api를 받아주기로 변경함으로써 해당 코드는 옮겨진다
    axios.get(`http://localhost:3001/surveys/${surveyId}`).then(
      (res) => {
        setServeyData(res.data);
      },
      [surveyId, setServeyData],
    );
  });*/

  return questions[step];
}

export default useCurrentQuestion;
김가을님의 프로필 이미지
김가을
질문자

감사합니다 오류 해결됐습니다 ㅠㅠ

덕분에 해결하였습니다 감사합니다!!

0

Daniel Choi님의 프로필 이미지

jotai 를 사용 시 questionsLengthState 에서

length를 읽어오지 못하는 케이스 처리가 모호하여

ActionButtons 컴포넌트에서 아래와 같이 변경했습니다.

// const questionsLength = useAtomValue(questionsLengthState);

const questionsLength = useAtomValue(surveyState).questions.length;

0

more j님의 프로필 이미지

어떤 부분에서 막히셨을까요 ? 알려주시면 코드 공유해드릴게요

김가을님의 프로필 이미지
김가을
질문자

안녕하세요 답변 감사합니다!

surveyState.js 작성에서 계속 막혀있는 상태입니다 ㅠㅠ
아래는 제가 작성해 본 코드예요

import axios from 'axios';
import { atom } from 'jotai';

const surveyState = atom(async () => {
  const res = await axios.get(
    `http://localhost:3001/surveys/${window.location.pathname.split('/')[2]}`,
  );

  console.log(res.data);

  return res.data;
});

export default surveyState;