[TIL] 리액트 데이터 다루기, 렉시컬s, This에 대하여

샤이니·2023년 4월 25일
0

learned.log

목록 보기
35/46

오늘의 나는 무엇을 새롭게 배웠나요?

[1] 리액트 데이터 다루기

1~2챕터 1/2를 수강했다.

props로 메서드 내리기

props로 메서드를 내려주면 자식 컴포넌트에서도 부모 컴포넌트의 메서드를 호출하고 다룰 수 있다.

function ParentComponent() {
  function handleClick() {
    console.log('Button clicked');
  }

  return (
    <div>
      <ChildComponent onClick={handleClick} />
    </div>
  );
}

function ChildComponent(props) {
  return (
    <button onClick={props.onClick}>
      Click me
    </button>
  );
}
  • ParentComponent의 handleClick 메서드가 ChildComponent의 onClick prop으로 전달되고, ChildComponent에서는 이를 사용해서 버튼 클릭 이벤트를 다룬다.

key를 사용해야 하는 이유

https://junior-datalist.tistory.com/184

https://ko.legacy.reactjs.org/docs/reconciliation.html#recursing-on-children

배열을 렌더링할 때 key를 지정하지 않으면 다음과 같은 오류가 뜨는 것을 볼 수 있다.

Key를 지정하더라도 배열의 인덱스 같이 데이터를 구분할 수 없는 고유하지 않은 값으로 Key를 지정하면 렌더링이 잘못될 수 있다.

요소마다 Key로 고유한 값을 지정해주면, 요소를 삭제, 추가하는 등 배열이 변경될 때, 정확히 어떤 요소가 변화한 것인지 알 수 있어서 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.

useEffect

useEffect(() => {
	handleLoad(); //callback
}, []);

첫번째 argument로 callback과 두번째 argument로 빈배열([])를 넣어주면 리액트는 콜백 함수를 맨 처음 렌더링할 때만 실행한다. (왜냐 빈배열은 계속 값이 같기 때문)

  • 첫번째 argument: callback은 리액트가 비동기로 실행할 함수
  • 두번째 argument: Dependency List

useEffect를 호출하면 리액트는 곧바로 콜백 함수를 실행하는 게 아니라, 콜백 함수를 예약해 뒀다가 렌더링이 끝나면 실행한다. 이때 Dependency List도 같이 기억해 콜백 함수를 실행하면 (만약 state를 변경하는 콜백이라면) state가 변경되니 다시 렌더링이 된다.

다시 렌더링 하면서 컴포넌트 함수를 실행하고 useEffect함수도 다시 실행되는데, Dependency List에 있는 값들을 앞에서 기억한 값이랑 비교한다. 기억했던 값과 다른 경우에만 콜백을 예약한다.(렌더링 후 실행)

페이지네이션(Pagination)

데이터를 나눠서 제공하는 것

1. Offset 기반 페이지네이션

  • Offset (상쇄하다) : 지금까지 받아온 데이터의 개수
  • GET https:~~posts?**offset=20&limit=10**
  • 단점: 일관성의 문제 - 사용자가 페이지를 탐색하는 동안 새로운 레코드가 추가되거나 삭제될 경우 데이터셋의 일관성이 손상될 수 있다. 페이지가 중복되거나 누락되는 등의 결과를 초래한다.

2. Cursor 기반 페이지네이션

  • Cursor : 데이터를 가리키는 값 = 지금까지 받은 데이터를 표시한 책갈피
  • GET https:~~posts?**limit=10** (10개 보내줘)을 보내면 서버는 response로
    {   // 페이지네이션 정보
    	"paging" : {
    		"count": 30,
    		"nextCursor" : "WerZxc" // 다음 cursor값
    	}.
    	"posts" : [..] //데이터
    }
    다음 request를 보낼 때, GET https:~~posts?cursor=WerZxc&limit=10 (커서 이후로 10개 보내줘) 이렇게 커서를 기준으로 서버에 데이터를 요청함

  • 단점 : 서버 입장에서는 커서기반이 오프셋 기반보다 만들기 까다로움

조건부 렌더링

**논리 연산자 활용하기**

~~~코드 있음
return (
    <div>
      <button onClick={handleClick}>토글</button>
      {show && <p>보인다 👀</p>}
    </div>
  );

show 값이 true 이면 렌더링 하고, false 이면 렌더링 하지 않는다.

**OR 연산자**

return (
    <div>
      <button onClick={handleClick}>토글</button>
      {hide || <p>보인다 👀</p>}
    </div>
  );

hide 값이 true 이면 렌더링 하지 않고, false 이면 렌더링 한다.

**삼항 연산자 활용하기**

return (
    <div>
      <button onClick={handleClick}>토글</button>
      {toggle ? <p></p> : <p></p>}
    </div>
  );

toggle 의 값이 참일 경우엔 '✅'을, 거짓일 경우에는 '❎'를 렌더링

**렌더링되지 않는 값들**

null, undefined, boolean값, ''(빈문자열), [](빈배열)은 렌더링하지 않습니다.

  • ex) return (<div><p>{**null**}</p><div>)

⛔주의 : 숫자 0과 1은 렌더링됨!

import { useState } from 'react';

function App() {
  const [num, setNum] = useState(0);

  const handleClick = () => setNum(num + 1);

  return (
    <div>
      <button onClick={handleClick}>더하기</button>
      {**num** && <p>num이 0 보다 크다!</p>}
    </div>
  );
}

export default App;

처음 실행했을 때 숫자 0이 렌더링 되고 '더하기' 버튼을 눌러서 num 값이 증가하면 num이 0 보다 크다! 가 렌더링된다. 따라서 {(**num > 0**) && <p>num이 0 보다 크다!</p>} 등으로 변경해야한다!

비동기로 State를 변경할 때 주의할 점

setState 호출이 비동기적으로 처리되기 때문에, state 변수가 항상 최신 상태를 반영하지 않을 수 있다

  • setter함수에 값이 아니라 callback을 전달해서 해결 - 즉 콜백 함수형 업데이트를 사용해 해결할 수 있다.

함수형 업데이트

이전 상태값을 콜백 함수에 전달해 새로운 상태값을 반환하는 방법

if (options.offset === 0) {
      setItems(reviews);
    } else {
      setItems((prevItems) => [...prevItems, ...reviews]);
    }
  • offset값이 0이 아닐 때 기존 items 배열과 새로 받아온 reviews배열을 합쳐서 새로운 배열을 만든 다음, 그 배열을 setItems를 함수를 통해 items state 값으로 설정한다.
    • 이때 setItmes 함수에 함수를 아규먼트로 전달하는데 (=즉 콜백) 이전 items 배열 값을 이용해서 새로운 items 배열을 만들어야할 경우 사용하는 방법이다.
    • 함수를 아규먼트로 전달하면 (콜백을 넣으면) React는 이전 items 배열의 값을 아규먼트로 전달하고, 새로운 state 값을 반환하는 함수를 실행한다.
    • https://velog.io/@tjdgus0528/React-Native-5x048oii

[2] This 탐구생활

this가 너무 헷갈려서, 특히 arrow Function에서의 this가 너무나도 헷갈려서 탐구해봤다.

[3] 배열을 렌더링할 때 key를 꼭 명시해야하는 이유

공부하면서 어떤 어려움이 있었나요?

렉시컬 환경과 렉시컬 스코프가 헷갈렸다.

렉시컬 환경(lexical environment)과 렉시컬 스코프(lexical scope)는 서로 밀접한 관련이 있지만 다른 개념이다.

렉시컬 환경은 변수 식별자(identifier)와 그 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조 등을 담고 있는 객체이다. 자바스크립트 코드가 실행될 때마다 해당 코드의 렉시컬 환경이 생성되며, 실행 컨텍스트 내부의 프로퍼티로 저장된다.

반면에 렉시컬 스코프는 함수가 정의될 때 결정되는 스코프의 범위를 뜻한다. 함수가 호출될 때가 아니라 함수가 정의될 때 스코프가 결정되므로, 실행 중에는 스코프를 변경할 수 없다. 이를 정적 스코프(static scope) 또는 어휘적 스코프(lexical scope)라고도 한다.

따라서, 렉시컬 환경은 실행 중에 생성되고 변경될 수 있지만, 렉시컬 스코프는 함수가 정의될 때 결정되고, 실행 중에는 변경될 수 없다는 점에서 차이가 있다.

내일의 나는 무엇을 공부해야 할까요?

  • 리액트 데이터 다루기 완강
  • 알고리즘 1문제
  • 피어리뷰에 대한 회고 작성
  • 몸 조리 잘하기..
    • 공부하는 데에는 문제가 없으나 사람들이랑 같이 있으니 기빨리는 하루..ㅠㅠ
    • 건강이 최고다! 잘자고 따뜻하게 입고, 당분간 마스크 쓰기 ㅎㅎ

0개의 댓글