[TIL] state & props, useEffect 활용 과제

ㅜㅜ·2022년 10월 12일
1

Today I learn

목록 보기
31/77
post-thumbnail

🤔 과제 : states airline client part-2

🟢 getFlight 함수 뜯어보기

: getFlight 함수 전에 FlightDataApi.js의 상단에서 로컬 스토리지로 flightList를 flight 키에 저장한 것을 가져와 json이라는 변수에 할당한다. 그리고 로컬 스토리지는 문자형 데이터 타입만 지원하기 때문에 JSON.parse를 써서 원래 형식을 살려준다.

get Flight 함수는 filterBy라는 매개변수에 전달인자를 전달 받거나 혹은 빈 객체를 전달인자로 받는다.(*js 문법 : 초기값 설정이라는 개념인데, 어떤 값이 들어오지 않으면 초기값을 전달인자로 받을 수 있다!!)

만약 window가 undefined가 아니라면***, 로컬 스토리지에 저장해뒀던 flight라는 키를 가진 데이터를 가지고 온다. 함수 내부에서 flight이라는 변수를 다시 선언한 뒤 위에서 원래 형식을 살려준 데이터 혹은 빈 배열을 넣는다. filtered라는 변수를 선언하고 flight이라는 배열을 filter 매서드를 사용해 순회하고, 받아온 데이터 리스트의 출발지와 도착지를 각각 getFlight 함수가 인자로 받은 조건과 비교해서 둘 다 동일한 경우의 데이터만 true에 해당하게 되고, true인 경우만 남게 된다.

즉, getFlight 함수는 Main에서 filterByCondition의 역할을 하는 함수라고 할 수 있는데, 이 함수는 React 컴포넌트와는 별개로 작동하는 함수로 'Side Effect'로 볼 수 있다. 그러므로 이 함수를 사용하기 위해서는 Effect Hook을 이용해서 처리해야 한다!

***이 조건문은 'window라는 객체가 있다면'으로 해석할 수 있음. 이 조건문은 실행하는 런타임(프로그래밍 코드를 실행하는 주체)가 브라우저인지 아닌지를 판별하는 조건문인데 런타임은 브라우저 외에도 node.js도 있기 때문에 만약 node.js라면 해당 조건문을 스킵함. node.js 런타임에는 window라는 객체가 없으므로. (출처 : 스터디 어느 천재의 가르침)
import flightList from "../resource/flightList";
import fetch from "node-fetch";

if (typeof window !== "undefined") {
  localStorage.setItem("flight", JSON.stringify(flightList));
}


export function getFlight(filterBy = {}) {
	let json = [];
  
	if (typeof window !== "undefined") {
      json = localStorage.getItem("flight");
  		}
  
  	const flight = JSON.parse(json) || [];

  	return new Promise((resolve) => {
  	const filtered = flight.filter((flight) => {
  	let condition = true;
  	if (filterBy.departure) {
  	condition = condition && flight.departure === filterBy.departure;
  		}
  	if (filterBy.destination) {
  		condition = condition && flight.destination === filterBy.destination;
  		}
  		return condition;
  		});

  	setTimeout(() => {
  	resolve(filtered);
  	}, 500);
  	});
}





🟢 fetch의 path 지정하는 방법

  • 가장 중요한 것은 문자열로 path를 전달해주어야 한다는 점! (백틱을 쓰든, 따옴표를 쓰든)

  • url을 그대로 입력해도 됐지만, url을 분해해서 변수들로 각각 지정해준 뒤 경로로 만들어줄 수도 있었다.


let url = `과제에서 준 url 넣는곳`;
  let departure = filterBy.departure;
  let destination = filterBy.destination;
//각 변수들에 filterBy에 전달인자로 받은 조건의 departure, destination 키 값을 각각 할당

  if (destination !== undefined) {
    return fetch(
      `${url}?destination=${destination}&departure=${departure}`
    ).then((el) => el.json());
  } else {
    return fetch(`${url}`).then((el) => el.json());
  }
//도착지가 입력되지 않았다면 모든 비행 목록이 나오는 화면 url만 경로로 전달하고, 
//그렇지 않은 경우 destination이 undefined가 아닌 경우에는 위에서 만든 변수들도 사용해 path를 지정해준다. 




🟢 useEffect, Loading Indicator 사용하기

: 로딩, 필터링, 필터링한 뒤 나온 비행기 리스트들을 모두 useEffect를 통해 구현하고, 요소들에도 속성으로 전달해주어야 했음.

const [isLoading, setIsLoading] = useState(true);
//초기값은 true를 권장**

useEffect(() => {
    setIsLoading(true);
    getFlight(condition).then((el) => {
      setFlightList(el);
      setIsLoading(false);
    });
  }, [condition]);


 {isLoading ? <LoadingIndicator /> : <FlightList list={flightList} />}
  //부분들만 따로 떼 온 것임. 
**초기값이 true여야하는 이유 : Effect Hook가 실행되기 전 데이터가 없는 화면을 출력하는 등의 상황을 방지하기 위함. 개발자는 데이터를 받아오기 전 로딩 화면으로 랜더링 되는 중인 화면을 가리고자 할 수 있는데, 초기값이 false이면 그렇게 동작하지 않음. (리턴문 내의 엘리먼트들이 먼저 렌더링 된 이후에 Effect Hook이 실행되기 때문에, 로딩과 관련한 state를 활용하려면 초기값을 true로 두는 것이 맞다.)




오답노트

  • Math.sqrt(x)는 전달인자 x의 제곱근 값을 구하는 매서드이고, 주어진 인자에 대해 항상 동일한 결과값을 리턴하므로 순수 함수.

  • 전역 객체 obj와 sum 함수의 매개변수로 들어가 있는 obj의 이름이 같아 깜빡 속음...

const obj = {value : 12};
function sum(obj, num){
  	return {value: obj.value + num};
}
//sum의 리턴값은 외부의 영향을 받아서 값이 바뀌지 않음.


//반면에 아래의 경우에는 
let c = 12;
function sum(a,b){
  return a+b+c
}
//c는 전역 변수이고, 함수 sum의 외부 변수이다.
//이 경우 인자로 받아오지 않은 c가 변함에 따라 함수의 결과값이 달라진다.

  • React의 가장 작은 단위는 엘리먼트(요소)이다 ^^... 컴포넌트는 이러한 여러 요소와 함수들이 모여있는 기능적인 단위임.
profile
다시 일어나는 중

0개의 댓글