React에서 막히는 곳은 대부분 React가 아니라 JavaScript입니다. 배열 함수, 비교 기호, 문법의 세 가지로 나누어 정리했습니다
map, filter, ...(스프레드)는 원래 배열을 바꾸지 않고 "새 배열"을 만듭니다. 그래서 React의 state와 잘 맞습니다
모르는 문법은 아래 표에서 한 문장짜리 "규칙"을 읽은 뒤 데모에서 직접 해 보세요
한눈에 보기
배열 함수
문법
규칙(한 문장)
예시
.map((x) => …)
하나씩 꺼내서 모양을 바꾼 새 배열을 만든다
members.map((m) => <li>{m.name}</li>)
.filter((x) => 조건)
조건에 맞는 것만 남긴 새 배열을 만든다
members.filter((m) => m.plan === "유료")
.find((x) => 조건)
조건에 맞는 첫 번째 하나를 돌려준다
members.find((m) => m.id === 2)
.sort((a, b) => 숫자)
두 개씩 비교해서 정렬한다. 결과가 음수면 a가 앞
[...items].sort((a, b) => a.price - b.price)
.slice(시작, 끝)
시작부터 끝 바로 앞까지 잘라 낸다 (0부터 센다)
items.slice(0, 6)
.reduce((합계, x) => …, 0)
하나씩 보면서 하나의 값(합계 등)으로 모은다
items.reduce((sum, i) => sum + i.price, 0)
.includes(x)
x가 들어 있는지 (true / false)
name.includes(query)
.length
배열이면 개수, 문자열이면 글자 수
{members.length}명
.some((x) => 조건)
하나라도 조건에 맞는 것이 있는지 (true / false)
items.some((i) => i.stock === 0)
.join(구분자)
배열을 구분자로 이어 붙인 하나의 문자열로 만든다
tags.join(", ")
비교하기·잇기
문법
규칙(한 문장)
예시
===
왼쪽과 오른쪽이 같은지
plan === "유료"
!==
왼쪽과 오른쪽이 같지 않은지
m.id !== id
> >= < <=
초과·이상·미만·이하
quantity >= stock
!
반대로 바꾼다 (true ↔ false)
!isOpen
&&
그리고. JSX에서는 "맞으면 보여 준다"
{error && <p>{error}</p>}
||
또는
!isDirty || isSubmitting
조건 ? A : B
맞으면 A, 아니면 B
{open ? "닫기" : "열기"}
a ?? b
a가 비어 있으면(null·undefined) b를 쓴다
user.name ?? "게스트"
a?.b
a가 비어 있어도 오류를 내지 않고 undefined가 된다
user?.name
문법
문법
규칙(한 문장)
예시
(x) => …
함수를 만든다 (x를 받아서 …한다)
() => setCount(count + 1)
(x) => { … }
안에 여러 줄을 쓸 수 있는 함수
onClick={() => { reset(); setSent(false) }}
const와 let
const는 다시 넣지 않고, let은 나중에 다시 넣는다
let sorted = filtered
const [a, setA] = …
돌아온 두 값에 이름을 붙여서 꺼낸다
const [count, setCount] = useState(0)
const { a, b } = …
상자({ }) 안에서 쓸 것만 이름으로 꺼낸다
const { user } = useAuth()
function X({ a })
컴포넌트에 전달된 것(props)을 이름으로 받는다
function Card({ title }) { … }
`…${x}…`
문자열 안에 값을 넣는다 (템플릿 리터럴)
`${count}건`
[...x, 추가]
배열을 복사하고 마지막에 추가한 새 배열
setMembers([...members, newMember])
{ ...x, 키: 값 }
객체 하나를 복사하고 한 곳만 바꾼 새 객체
{ ...member, id: 7 }
import / export
다른 파일의 컴포넌트를 쓴다 / 다른 파일에서 쓸 수 있게 내보낸다
import { Button } from "./button"
async / await
시간이 걸리는 일(데이터 가져오기 등)이 끝나기를 기다린다
const res = await fetch(url)
직접 해 보기
import{useState}from"react"// 회원 목록 (처음 3명)constinitialMembers = [{id:1,name:"김민준",plan:"유료"},{id:2,name:"이서연",plan:"무료"},{id:3,name:"박지훈",plan:"유료"},]exportdefaultfunctionApp(){// 회원 목록 ("1명 추가"로 늘어남)const[members,setMembers] = useState(initialMembers)// "유료만 보기"가 눌려 있는지 (true = 눌려 있음)const[paidOnly,setPaidOnly] = useState(false)// 화면에 보여 줄 목록: 눌려 있으면 유료 회원만, 아니면 전원constshown = paidOnly ? members.filter((member)=>member.plan === "유료") : members// 1명 추가: 지금 회원을 모두 나열하고 그 마지막에 새 1명을 더한 목록으로 만든다functionaddMember(){constnewId = members.length + 1setMembers([...members,{id:newId,name:"회원" + newId,plan:"무료"}])}return(<divstyle={{padding:16,fontFamily:"sans-serif"}}><divstyle={{display:"flex",gap:8}}>{/* 누를 때마다 유료만 ↔ 전원 을 전환한다 (! = 반대로 바꾸기) */}
<buttononClick={()=>setPaidOnly(!paidOnly)}>{paidOnly ? "전원 보기" : "유료만 보기"}</button><buttononClick={()=>addMember()}>1명 추가</button></div><p>{shown.length}명</p>{/* 화면에 보여 줄 목록을 한 명씩 "이름 (플랜)" 줄로 만든다 */}
<ul>{shown.map((member)=>(<likey={member.id}>{member.name} ({member.plan})
</li>))}</ul></div>)}