[Velopert리액트1]리액트 입문2

Yongrok·2021년 12월 29일
0

React_Velopert

목록 보기
2/9

사용교재 : 벨로퍼트와 함께하는 모던 리액트
범위 : 1.10 ~ 1.20
노션 용량문제로 Migration

10. useRef

특정 DOM을 선택할 때 사용하는 Hook함수로, 열린 태그의 ref속성을 통해 사용.

useRef()Ref객체 생성 → 선택할 DOM에 ref값으로 설정 → .current값은 선택한 DOM을 가리킴

function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
  const nameInput = useRef();

  const { name, nickname } = inputs;

  const onChange = e => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs,
      [name]: value
    });
  };

  const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  };

  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
			<input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

11. 배열 렌더링

map() 을 통해 동적으로 값을 전개하여 렌더링

  return (
    <div>
      {users.map(user => (
        <User user={user} key={user.id}/>
      ))}
    </div>
  );

key : 리액트에서 배열을 렌더링 할 때 반드시 설정해야하는 props. key 값은 각 원소의 고유값으로 설정.

key 가 있어야 배열이 업데이트 될 때 렌더링이 효율적

(?) key 유무

  1. key 있다
    배열에 신규값이 추가/삭제하고 리렌더링 했을 때,
    기존값은 그대로 두고 새로운 배열값을 적절한 위치에 삽입/삭제.
  2. key 없다
    배열에 신규값이 추가/삭제하고 리렌더링 했을 때,
    원하는 위치의 기존값을 새로운 배열값으로 변경
    → 이후의 값들도 쭉 밀리며 변경

useRef 의 변수 관리

useRef 로 컴포넌트 안에서 조회/수정 가능한 변수를 관리하는 것이 가능

useRef 로 관리하는 변수는 값이 바뀌어도 리렌더링 X

→ 리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출한 뒤에야 업데이트된 상태를 조회가능
useRef 로 관리하는 변수는 설정 후 바로 조회가능

  • 주 사용처
    • setTimeoutsetInterval 을 통해서 만들어진 id
    • 외부 라이브러리를 사용하여 생성된 인스턴스
    • scroll 위치
const nextId = useRef(4);
const onCreate = () => {
  // 나중에 구현 할 배열에 항목 추가하는 로직
  nextId.current += 1;
};

useRef() 의 파라미터 : .current 의 기본값. .current 를 수정해서 해당 변수값을 조작한다.

13. 배열에서 항목 추가하기

불변성을 지켜야 한다!
push, splice, sort 등의 함수 사용금지

  • ... spread 연산자 사용
const [users, setUsers] = useState([
	{
		id: 1,
		username: 'velopert'
	}
]);

const nextId = useRef(4);
const onCreate = () => {
	const user = {
	id: nextId.current,
	username
	};
	setUsers([...users, user]);
	
	nextId.current += 1;
};
  • concat 함수 사용
const [users, setUsers] = useState([
    {
      id: 1,
      username: 'velopert'
    }
]);  

const nextId = useRef(4);
const onCreate = () => {
  const user = {
    id: nextId.current,
    username
  };
  setUsers(users.concat(user));

  nextId.current += 1;
};

14. 배열에서 항목 제거

불변성을 지켜야 한다!
filter 함수 추천 → 특정 조건만 만족하는 새로운 배열을 만들기 때문

const onRemove = id => {
// user.id 가 불일치하는 원소만 추출해서 새로운 배열을 만듬
// 결과적으로, user.id === id 인 것을 제거
  setUsers(users.filter(user => user.id !== id));
};

15. 배열에서 항목 수정

불변성을 지켜야 한다!
map 함수 사용하여 수정할 항목을 특정하고, 값을 변경 → 수정사항이 적용된 새로운 배열이 탄생 → 새로운 배열로 상태 교체

const onToggle = id => {
  setUsers(
    users.map(user =>
      user.id === id ? { ...user, active: !user.active } : user
    )
  );
};

16. useEffect

특정 상황에서의 작업 처리

  • 컴포넌트가 마운트 됐을 때 (최초 등장)
    • props 로 받은 값을 컴포넌트의 로컬 상태로 설정
    • 외부 API 요청
    • 라이브러리 사용
    • setInterval (반복작업), setTimeout (작업예약)
  • 컴포넌트가 언마운트 됐을 때 (사라짐)
    • setInterval , setTimeout 으로 등록한 작업 clear
      clearInterval , clearTimeout
  • 컴포넌트가 업데이트 될 때 (특정 props가 바뀜)
useEffect(() => {
  console.log('컴포넌트가 화면에 나타남');
  return () => {
    console.log('컴포넌트가 화면에서 사라짐');
  };
}, []);

useEffect(paramA, paramB)

  • paramA : 함수
    • cleanup 함수
      • useEffect 에서 반환하는 함수
      • useEffect 의 뒷정리를 함
      • deps 가 비어있을 때 호출됨
  • paramB : 의존값이 들어있는 배열 deps → 생략시 컴포넌트가 처음 나타날 때에만 useEffect 에 등록한 함수가 호출됨

deps

deps 배열에 특정값이 있다면!

  • 컴포넌트 마운트 될 때 호출
  • 지정한 값이 바뀔 때 호출
  • 언마운트 될 때 호출
  • 값이 바뀌기 직전에도 호출

필수!

useEffect 내부에서 사용하는 상태, props는 deps 에 반드시 추가한다.
(?) 추가하지 않을 시
useEffect 에 등록한 함수가 실행될 때 최신 상태, props를 반영 X

17. useMemo

연산된 값을 재사용하여 성능 최적화를 돕는 기능

useMemo(paramA, paramB)

  • paramA : 함수. 어떻게 연산할 지.
  • paramB : deps 배열.
    배열에 속한 값이 변경되면, paramA 함수를 호출.
    변경되지 않으면, 기존값을 사용

18. useCallback

특정 함수를 재사용
props 가 변경되지 않으면 Virtual DOM이 새로 렌더링되지 않게 최적화하는 과정에 필요한 기능

const [users, setUsers] = useState([
  {
    id: 1,
    username: 'velopert',
    email: 'public.velopert@gmail.com',
    active: true
  }
]);

const onToggle = useCallback(
  id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  },
  [users]
);

필수!

useEffect 내부에서 사용하는 상태, props는 deps 에 반드시 추가한다.
(?) 추가하지 않을 시
useEffect 에 등록한 함수가 실행될 때 최신 상태, props를 반영 X
useMemo 와 비슷하다. 기원이 useMemo 라서...

19. React.memo로 리렌더링 막기!

컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록 설정가능

사용법: 필요한 부분을 React.memo() 로 감싸기
→ 다른 컴포넌트와 공통된 값을 deps 에서 공유하고 있다면, 연쇄적으로 리렌더링 됨
→ 공통 deps 제거 및 함수형 업데이트

ex) setUsers(users.concat(user))
setUsers(users => users.concat(user))

20. useReducer

useState 처럼 상태를 관리하는 기능

VS useState

  • 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리 가능
    (컴포넌트 바깥, 별개의 파일에서 불러오기)
  • const [state, dispatch] = useReducer(reducer, initialState);
    • state : 상태
    • dispatch : 액션을 발생시키는 함수 dispatch({type: "액션"})
    • reducer : 액션에 따른 상태관리 기능을 가진 함수
    • initialState : 초기 상태
  • 컴포넌트에서 관리하는 값이 많다 → 상태의 구조가 복잡하다
    = useReducer 가 더 편할 수 있다

0개의 댓글