와챠의 우당탕탕 코딩 일기장

[React]#5- Inflearn: 만들면서 배우는 리액트: 기초/OpenAPI를 사용해 고양이 데이터 받아오기/useEffect/setState 성능 개선 본문

코딩 일기장/React

[React]#5- Inflearn: 만들면서 배우는 리액트: 기초/OpenAPI를 사용해 고양이 데이터 받아오기/useEffect/setState 성능 개선

minWachya 2023. 1. 21. 14:02
반응형

* #3, #4는 생략 및 다른 강의노트에 추가함.

 

목차

  1. 시작하기 전에
  2. 사용자 입력에 따라 실행: 폼 제출 시마다 폼 입력값으로 고양이 짤방 만들기
  3. 웹 시작 시 실행: 웹 시작 시에 first cat이 써진 고양이로 메인 고양이 사진 초기화하기
  4. useEffect란?
  5. setState의 성능 개선

1. 시작하기 전에

  1. open API 모음 깃허브에서 고양이 짤방 api를 사용하여 고양이 짤방 기능을 추가할 것임
  2. fetch 사용하기 문서에서 가져온 fetch 사용법
  3. fetch('http://example.com/movies.json') .then((response) => response.json()) .then((data) => console.log(data));
  4. js 비동기 처리와 콜백 함수 문서
    1. 비동기 처리하는 법: 콜백함수
    2. 콜백함수 지옥 해결하는 법: 각 콜백함수 분리해주기
  5.  js Promise 쉽게 이해하기 문서
    1. js Promise란? 자바스크립트 비동기 처리에 사용되는 객체
    2. 언제 사용? 서버에서 받아온 데이터를 화면에 표시할 때 사용
    3. Promise 3가지 상태
      1. Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
      2. Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
      3. Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
  6. js asyn와 await 문서
    1. async와 await는 자바스크립트의 비동기 처리 패턴 중 가장 최근에 나온 문법
async function 함수명() {
  await 비동기_처리_메서드_명();
}

//-----------

async function logName() {
  var user = await fetchUser('domain.com/users/1');
  if (user.id === 1) {
    console.log(user.name);
  }
}

2. 사용자 입력에 따라 실행: 폼 제출 시마다 폼 입력값으로 고양이 짤방 만들기

// 고양이 api를 사용해 고양이 짤방을 불러오는 코드
const fetchCat = async (text) => {
	// base url
	const OPEN_API_DOMAIN = "https://cataas.com";
    // response를 json으로 받아오기 
	const response = await fetch(`${OPEN_API_DOMAIN}/cat/says/${text}?json=true`);
    // json값만 저장
	const responseJson = await response.json();
    // json의 url 반환
	return `${OPEN_API_DOMAIN}/${responseJson.url}`;
};

 

위 코드는 text값을 보내면 해당 text가 그려진 고양이 짤방 url을 반환하는 코드이다.

async await를 사용해 비동기로 해당 기능을 처리한다.

 

폼의 input값을 얻어 fetchCat에 text를 보내주어야 한다.

폼의 입력값을 받은 뒤 해당 입력값을 updateMainCat으로 전달하는 방법을 사용한다.

const Form = ({ updateMainCat }) => {
      // 폼 사용자 입력값
      const [value, setValue] = React.useState("");
      
      // ...

		// 입력할 때마다 동작
      function handelFormSubmit(e) {
        e.preventDefault();
        
        // 입력값 검증... 생략

        // 입력값 검증 후 실행
        updateMainCat(value);
      }

      return (
        <form onSubmit={handelFormSubmit}>
          <input
            type="text"
            name="name"
            value={value}
            placeholder="영어 대사를 입력해주세요"
            onChange={handelInputChange}
          />
          <button type="submit">생성</button>
        </form>
      );
    };

 

updateMainCat은 최상위 컴포넌트인 app내에 있다.

async await을 사용해주기 위해 function앞에 async, fetchCat앞에 await를 붙여주면 끝!!

// 전체 출력
    const App = () => {
      // ...

      // 폼 제출 시 메인 사진 변경
      async function updateMainCat(value) {
        const newCat = await fetchCat(value);
        setMainCatImage(newCat);
      }

		// ...

      return (
        <div>
          <Title>{counter}번째 고양이 가라사대</Title>
          <Form updateMainCat={updateMainCat} />
          <MainCard img={mainCatImage} onHandleHeartClick={handleHeartClick} />
          <Favorites favorites={favorites} />
        </div>
      );
    };

그럼 이제 폼 제출 시마다 폼의 입력값을 담은 고양이 짤방이 생기는 걸 확인할 수 있다.

귀엽다


3.  웹 시작 시 실행: 웹 시작 시에 first cat이 써진 고양이로 메인 고양이 사진 초기화하기

// 메인 고양이 초기화
      async function setInitCat() {
        const newCat = await fetchCat('first cat');
        setMainCatImage(newCat);
      }
// 한 번만 실행
React.useEffect(() => {
        setInitCat();
      }, []);

4. useEffect란?

리액트 컴포넌트 안의 코드는 ui가 업데이트 될 때마다 새로 불려짐.

 

useEffect는 ui가 업데이트 될 때마다가 아니라 내가 원할 때마다 새로 불러오고 싶을 때 사용한다.

 

useEffect의 2번째 인자:

빈 배열([]) 사용: 컴포넌트가 맨 처음 나타날 때만 불림

인자 있는 배열([counter]) 사용: counter가 바뀔 때마다 새로 불림(counter는 Rreact.useState로 타이틀의 n번째 고양이의 n임)


5. setState의 성능 개선

ex1) 로컬 스토리지에 한 번만 접근하도록 하기

// 변경 전: 업데이트할 때마다 실행됨
//        로컬 스토리지에 계속 접근함: 시간이 조금 걸리는 작업
const [counter, setCounter] = React.useState(
        jsonLocalStorage.getItem('counter')
      );
      
// ------------

// 변경 후: 함수를 사용하여 한 번만 초깃값을 받게 함
const [counter, setCounter] = React.useState(() => {
        return jsonLocalStorage.getItem('counter');
      });

 

ex2) value, setValue 일치하게 하기

// 변경 전: 폼 제출을 연속으로 했을 때, counter와 setCounter가 가르키는 counter가 불일치 할 수 있음

// 폼 제출 시 타이틀 숫자 증가
async function updateMainCat(value) {
		// ,,,

        const nextCounter = counter + 1
        setCounter(nextCounter);

        jsonLocalStorage.setItem('counter', nextCounter);
      }
      
// --------------

// 변경 후: counter와, setCounter가 가르키는 counter 일치
// 폼 제출 시 타이틀 숫자 증가
      async function updateMainCat(value) {
        // ,,,

        setCounter((prev) => {
          const nextCounter = prev + 1
          jsonLocalStorage.setItem('counter', nextCounter);

          return nextCounter;
        });
      }

 

반응형
Comments