학습 예제 출처: 수코딩
- 상태선언 및 관리하는데 사용
- 리액트에서 변수 사용은 =>
useState()
로 한다 !- 기본적으로 useState = 배열[값,function함수] 다
└> 리액트가 관리하는 변수인지 확인 -> 변경
[ 값, set값 ] = useState();
set값()
로 변경하고싶은 값setNum(15)
로 바꿔주면 -> 변경 완료!
불변성(Immutability)이란?
불변성을 지켜서 값을 변경해줘야 함
= 즉, 새로운 배열
을 만들어서 거기에서 변경
해주기 ! ⭐
= 비동기 방식
임
🔎 동기와 비동기 차이?
동기
: 끝날 때까지 기다렸다가 작업
비동기
: 끝나기 전에 기다리지 않고 작업하는 것
useState 변경 -(2가지 방법)
1) 그냥 값을 set으로 넘겨주거나 ->
비동기
2) 콜백함수로 return값을 넘길 수도 있음 ->동기
: 타입 맞춰서 반환 값 필수!!const [num, setNum] = useState(1); const oncClickHandler = () => { //현재 자기자신의 값을 매개변수로 전달받음 setNum((num) => num + 1); console.log(num); };
이전 값을 참조해서 최신 상태값이 안궁금할 때는 무조건 1)비동기 방식으로!
🫨무슨 소리인가 싶지만, 예시를 봐보자!
기존에 벤츠/기아
였는데 이벤트에 의해서 현대
로 바꼈다면 이전 값이 안 궁금한거다!
최신 값을 보장하지 않는다! 💡
그럼 이땐, setCar(["현대"])
로 무조건 써주자!
그런데, 벤츠/기아/현대
로 바꾸고싶다면 이전 값이 궁금하니까
그럼 이땐, setCar(()=>["현대"])
로 무조건 써주자!
count 숫자 증가/ 감소 / 리셋
const [count, setCount] = useState(0);
const onClickDec = () => setCount((prev) => prev - 1);
const onClickReset = () => {
setCount(0);
};
const onClickAdd = () => {
setCount((prev) => prev + 1);
};
form 제출
e.target.value
= 적고있는 무언가
(e) => setText(e.target.value)
💡 value
<-> onChange
는 짝꿍처럼 생각하자!
value={text}가 없으면 초기화 코드를 적어줘도 초기화가 안됨
setText("")
//로그인 페이지
// 1, form태그의 submit으로 할건지
//2. button태그 클릭 -> button 타입을 type ="button" = 값 전달 가능 (콘솔에 띄움)
//onClick안써도됨 submit이 내장전송이니까 -> form onSubmit ={이벤트 핸들러}
//새로고침되지않고 전송할 수 있음
return (
<>
<form onSubmit={onClick}>
<input
type="text"
value={email}
placeholder="Enter Email"
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
value={password}
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">전송</button>
</form>
</>
);
state를 일괄적으로 객체로 관리하는 방법
name:이름 같아야함
| : 타입오퍼레이트
로 처리해준다custom hook
setter함수는 안내보내고,
비구조할당을 할때 내 맘대로 이름을 지어줄 수 있음
별도로 함수를 뻈기때문에
tailwind는 변수치환하는게 안됨
=>
useRef( ) 훅 ⭐
: 접근하려면
.current
랑 꼭! 같이 써야 useRef를 참조할 수 있다
useState
는 원래 <> 제네릭 타입
이다useRef 사용 방법 / 이유
렌더링과 상태변화에 영향을 주지 않고, 컴퍼넌트에서
값이 로직적으로만 저장하고싶을 때 사용한다.
성능이 훨씬 더 좋다!
DOM element
에 접근
하기 위해 사용됨
└> 🔎 무슨 뜻일까?
컴포넌트가 다시 렌더링되는 기준
: 화면이 달라질 때만 렌더링되는데, 상위컴퍼넌트가 변경되면 하위까지 다 렌더링된다.
🔎 그럼, useRef 언제 사용하나?
진짜 찐 보여주고싶어서 설계한 useState를 맨 상위 컴퍼넌트가 아니라 아래 컴퍼넌트에다 설계하자!
그래야지 똑같이 보이는 화면인데 렌더링 성능을 높일 수 있음!
useRef는 리액트 html 참조 용도로 쓰임
= javascriptfocus()
와 같음 : 커서 깜빡
ComponentPropsWithoutRef -> ComponentPropsWithRef로 변경해주면 타입오류안남
어려우니까 그냥 암기하자,,,! 🫨
⭐ 컴퍼넌트에 ref를 전달해야 할 때는 아래방법처럼 하자!!!
: 거의 input컴퍼넌트 , checkbox 컴퍼넌트에서 할 확률이 90%임...
ComponentPropsWithRef로 변경해줘도 안될거다
( x )
그 Input컴퍼넌트(해당 컴퍼넌트)에 가서
forwarRef
를 사용해야할 수 밖에 없음
( o )
import { forwardRef } from "react";
type TInputProps = Omit<React.ComponentPropsWithRef<"input">, "type"> & {
type: "text" | "password" | "email" | "number" | "date";
};
const Input = forwardRef<HTMLInputElement, TInputProps>(
(props: TInputProps, ref) => {
const { ...rest } = props;
return (
<>
<input
ref={ref}
className="inter h-[44px] text-sm border border-[#4f4f4f] py-[13.5px] px-[16px] rounded-lg placeholder-[#acacac]"
{...rest}
/>
</>
);
}
);
Input.displayName = "Input"; //이렇게 마지막에 받아야 함
export default Input;
——————————————————————————
본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프로젝트 캠프 : React 2기 과정(B-log) 리뷰로 작성 되었습니다.