1~2챕터 1/2를 수강했다.
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>
);
}
https://junior-datalist.tistory.com/184
https://ko.legacy.reactjs.org/docs/reconciliation.html#recursing-on-children
배열을 렌더링할 때 key를 지정하지 않으면 다음과 같은 오류가 뜨는 것을 볼 수 있다.
Key를 지정하더라도 배열의 인덱스 같이 데이터를 구분할 수 없는 고유하지 않은 값으로 Key를 지정하면 렌더링이 잘못될 수 있다.
요소마다 Key로 고유한 값을 지정해주면, 요소를 삭제, 추가하는 등 배열이 변경될 때, 정확히 어떤 요소가 변화한 것인지 알 수 있어서 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다.
useEffect(() => {
handleLoad(); //callback
}, []);
첫번째 argument로 callback과 두번째 argument로 빈배열([]
)를 넣어주면 리액트는 콜백 함수를 맨 처음 렌더링할 때만 실행한다. (왜냐 빈배열은 계속 값이 같기 때문)
useEffect를 호출하면 리액트는 곧바로 콜백 함수를 실행하는 게 아니라, 콜백 함수를 예약해 뒀다가 렌더링이 끝나면 실행한다. 이때 Dependency List도 같이 기억해 콜백 함수를 실행하면 (만약 state를 변경하는 콜백이라면) state가 변경되니 다시 렌더링이 된다.
다시 렌더링 하면서 컴포넌트 함수를 실행하고 useEffect함수도 다시 실행되는데, Dependency List에 있는 값들을 앞에서 기억한 값이랑 비교한다. 기억했던 값과 다른 경우에만 콜백을 예약한다.(렌더링 후 실행)
데이터를 나눠서 제공하는 것
GET https:~~posts?**offset=20&limit=10**
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값
, ''
(빈문자열), []
(빈배열)은 렌더링하지 않습니다.
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>}
등으로 변경해야한다!
setState 호출이 비동기적으로 처리되기 때문에, state 변수가 항상 최신 상태를 반영하지 않을 수 있다
이전 상태값을 콜백 함수에 전달해 새로운 상태값을 반환하는 방법
if (options.offset === 0) {
setItems(reviews);
} else {
setItems((prevItems) => [...prevItems, ...reviews]);
}
items
배열과 새로 받아온 reviews
배열을 합쳐서 새로운 배열을 만든 다음, 그 배열을 setItems
를 함수를 통해 items
state 값으로 설정한다.setItmes
함수에 함수를 아규먼트로 전달하는데 (=즉 콜백) 이전 items
배열 값을 이용해서 새로운 items
배열을 만들어야할 경우 사용하는 방법이다.items
배열의 값을 아규먼트로 전달하고, 새로운 state 값을 반환하는 함수를 실행한다.this가 너무 헷갈려서, 특히 arrow Function에서의 this가 너무나도 헷갈려서 탐구해봤다.
렉시컬 환경(lexical environment)과 렉시컬 스코프(lexical scope)는 서로 밀접한 관련이 있지만 다른 개념이다.
렉시컬 환경은 변수 식별자(identifier)와 그 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조 등을 담고 있는 객체이다. 자바스크립트 코드가 실행될 때마다 해당 코드의 렉시컬 환경이 생성되며, 실행 컨텍스트 내부의 프로퍼티로 저장된다.
반면에 렉시컬 스코프는 함수가 정의될 때 결정되는 스코프의 범위를 뜻한다. 함수가 호출될 때가 아니라 함수가 정의될 때 스코프가 결정되므로, 실행 중에는 스코프를 변경할 수 없다. 이를 정적 스코프(static scope) 또는 어휘적 스코프(lexical scope)라고도 한다.
따라서, 렉시컬 환경은 실행 중에 생성되고 변경될 수 있지만, 렉시컬 스코프는 함수가 정의될 때 결정되고, 실행 중에는 변경될 수 없다는 점에서 차이가 있다.