ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] Udemy 강의 노트 10-2
    WEB Dev/StudyNote 2023. 2. 9. 22:56
    728x90

     

     

    useReducer & useEffect

    - 입력은 전체 폼의 일부이다.

    - 코드가 너무 일찍 실행된 경우에는 useEffect는 state 업데이트 후에만 실행됐었다.

    - 의존성은 state 전체이지 유효성이 아니다.

    - 객체의 특정 속성을 추출하는 객체 디스트럭처링을 이용할 수 있다. 

    - const { isValid: emailIsValid } = emailState; 로 emailState의 isValid state를 emailIsVaild라는 상수로 별칭할당을 할 수 있다.

     

     

    중첩 속성을 useEffect에 종속성으로 추가하기

    - useEffect()에 객체 속성을 종속성으로 추가하기 위해 distructuring을 사용 

    const { someProperty } = someObject;
    useEffect(()=>{
      //code that only uses someProperty...
    }, [someProperty])

    - 매우 일반적인 패턴 및 접근 방식

    - 핵심은 전체 개체 대신 특정 속성을 종속성으로 전달한다는 것

    - 코드는 아래와 같이 작성할 수도 있지만 그것보다 위와 같이 someProperty를 종속성으로 전달하는 것을 추천한다.

    - 이유는 useEffect 훅은 someObject가 변경될 때마다 재실행되기 때문이다. (someObject는 단일 속성이 아니기 때문)

    useEffect(()=>{
      
    }, [someObject])

     

     

     

    State 관리를 위한 useReducer 대 useState

    - 일반적으로 useReducer가 필요한 때는 useState를 이용하면 너무 많은 일을 처리해야 해서 번거로워질 때다. 

    - useState는 주요 state 관리 툴이다.

    - 개별 state 및 데이터들을 다루기에 적합하다.

    - state 업데이트가 쉽고 몇 개 되지 않을 때 추천한다.

    - 만약 state로서의 객체나 복잡한 state가 있으면 useReducer를 고려할 수 있다.

    - 연관된 state 조각들로 구성된 관련 데이터를 다루는 경우이다.

    - 특히 폼이나 인풋 등의 state에 권장한다.

    - state 하나를 변경하는 여러 다른 액션이 있을 때도 권장한다.

     

     

     

     

     

     

    리액트 Context (Context API) 소개

    - 프롭스를 통해 많은 컴포넌트를 거쳐 스테이트를 관리할 때 생기는 문제

    - state를 여러 컴포넌트를 통해 전달하는 경우 props를 이용한다.

    - 하위 컴포넌트들 사이에서 연속되는 관계가 없지만 state를 전달해야 할 때 모든 컴포넌트에 접근할 수 있는 가장 상위인 App 컴포넌트를 사용하게 되면서 전혀 상관없는 컴포넌트들을 거쳐 state를 전달하게 된다. -> 프롭 체인 prop chain !!!

     

     

    - 부모를 통해 데이터를 전달하지 않도록 해야한다.

    - 이를 위해 리액트에 내장된 내부적인 state 저장소가 있다.

     

     

     

     

    리액트 컨텍스트 API 사용

    - 리액트 내의 context는 state를 관리하게 해주는 거으로 앱의 어떤 컴포넌트에서 다른 컴포넌트로 직접 state를 전달하게 해준다.

    - React.createContext()로 컨텍스트 객체를 생성한다. 

    - createContext는 기본 컨텍스트를 만든다. 대부분의 경우에 객체이다.

    - 이 객체를 변수에 담아 export 하여 내보낼 수 있다.

    - 리액트가 context를 사용하기 위해 해야할 일은 먼저 공급해야 하고, 접근 권한이 있어야 한다.

    - 공급은 항상 첫 번째로 해야 하는 일로 그 컨텍스트를 활용할 수 있어야 하는 모든 컴포넌트를 JSX 코드로 감싸는 것을 말한다. 

    - JSX 코드 내에서 .을 이용해 provider에 접근할 수 있다.<AuthContext.provider>

    - 이를 이용해 다른 컴포넌트 및 자손 컴포넌트는 해당 컨텍스트에 접근할 수 있다.

    - 값에 접근하려면 리스닝 해야 하는데 두 가지 방법으로 리스닝 할 수 있다.

    - context 소비자(Consumer) 또는 리액트 훅을 사용한다.

    - 일반적으로 리액트 훅을 사용한다.

    - consumer은 함수를 자식으로 가진다. 

    - 기본값은 공급자 없이 소비하는 경우에만 사용된다. 

     

     

     

    useContext 훅으로 컨텍스트에 탭핑(tapping)하기

    - useContext 훅은 컨텍스트를 사용할 수 있게 해준다.

    - 리액트 컴포넌트 함수에서 useContext를 호출하고 컨텍스트에게 사용하려는 컨텍스트를 가리키는 포인터를 전달한다. 

    - const ctx = useContext(AuthContext);

     

     

     

    컨텍스트를 동적으로 만들기

    - value에 함수를 가리키도록 할 수 있다.

    - props는 컴포넌트를 구성하고 그것들을 재사용할 수 있도록 하는 매커니즘

    - 따라서 많은 컴포넌트를 통해 전달하고자 하는 것이 있는 경우에만, 그리고 매우 특정적인 일을 하는 컴포넌트로 전달하는 경우에만 컨텍스트를 사용하는 것이 좋다.

     

     

     

    사용자 정의 컨텍스트 제공자 구성요소 빌드 및 사용

    - VSCode는 기본 context 객체를 보고 컨텍스트에서 접근할 수 있는 것을 찾기 때문에 provider value에 값을 넣더라도 기본 context 객체에 선언해주면 편하게 쓸 수 있다.

    - 전체 인증 state를 별도의 공급자 컴포넌트 (auth-context.js)에서 관리할 수 있다.

     

     

     

    리액트 컨텍스트 제한

    - 리액트 컨텍스트는 앱 전체 또는 컴포넌트 전체 state에는 적합할 수 있다.  (여러 컴포넌트에 영향을 미치는 state)

    - 매 초 또는 1초에 여러번 state가 변경되는 경우처럼 변경이 잦은 경우에는 리액트 컨텍스트는 적합하지 않다.

    - 몇 분에 한 번씩 바뀌는 경우는 컨텍스트를 쓸 수 있다.

    - 앱 전체 또는 컴포넌트 전체에 걸쳐 state가 자주 변경되는 경우에는 더 나은 도구가 있다. 이것이 리덕스이다.

    - 프롭의 모든 커뮤니케이션을 컨텍스트가 대체할 수 없다.

    - 긴 프롭 체인을 교체하기 위해서는 고려할 만 하다.

     

     

     

     

    "Hook의 규칙" 배우기

    - 두 개의 메인 규칙

    - 리액트 훅은 use로 시작하는 모든 함수로 리액트 훅은 리액트 함수에서만 호출해야한다. (리액트 컴포넌트 함수)

    - 또는 사용자 정의 훅에서도 호출할 수 있다.

    - 두 번째는 리액트 훅은 리액트 컴포넌트 함수 또는 사용자 정의 훅 함수의 최상위 수준에서만 호출해야 한다. 

    - 중첩문이나 block 문, 조건문, 훅 안에서 훅을 호출해서는 안된다.

    - 특정 훅인 useEffect는 참조하는 모든 항목을 의존성으로 useEffect 내부에 추가해야 한다.

    - useReducer 또는 useState에 의해 노출된 state 업데이트 함수는 변경되지 않도록 리액트가 보장한다.

    - 브라우저에서 오지 않거나 또는 컴포넌트 함수 외부에서 오는 데이터들 외에 useEffect를 사용하는 컴포넌트 함수 내부에서 오는 데이터들은 의존성 배열로 가야 한다.

     

     

     

     

     

    입력 컴포넌트 리팩토링

     

    Forward Refs 에 대해 알아보기

    - input 컴포넌트와 명령형으로 상호작용하게 해준다.

    - 어떤 state를 전달해서 그 컴포넌트에서 뭔가를 변경하는 것이 아니라 컴포넌트 내부에서 함수를 호출하는 방식

    - 일반적인 리액트 패턴은 아니다.

    - 일반적인 input이라면 ref를 사용하면 된다.

    - 함수 컴포넌트는 ref를 받을 수 없다 Function components cannot be given refs.

    - 그래서 ref를 사용할 수 없고 props 객체에서 ref prop을 받아들이지 않는다.

    - 제대로 작동시키기 위해서는 input 컴포넌트에서 useImperativeHandle 훅을 import 한다.

    - useImperativeHandle은 컴포넌트나 컴포넌트 내부에서 오는 기능들을 명령적으로 사용할 수 있게 해준다.

    - 일반적인 state 프롭 관리를 통하지 않고 부모 컴포넌트의 state로 컴포넌트를 제어하지 않고 프로그래밍적으로 컴포넌트에서 직접 호출하거나 조작하게 해준다.

    - useImperativeHandle을 호출하고 두 가지를 넣어준다 

    - 첫 번째 인자는 컴포넌트에서 props를 받아오는 것 처럼 ref를 받아와서 넣어준다.

    - 두 번째 인자인 함수에서 반환하는 것은 객체여야 하고 이 객체는 외부에서 사용할 수 있는 모든 데이터를 포함한다.

    - ref 를 활성화 시키려면 input 컴포넌트 함수를 특별한 방법으로 내보내야 한다.

    - React.forwardRef로 감싸준다.

     

     

    const Input = React.forwardRef((props, ref) => {
    	const inputRef = useRef(); 
    
    	const activate = () => {
    		inputRef.current.focus();
    	}
    
    	useImperativeHandle( ref , ()=>{
    		return {
    			focus: activate,
    		}
    	});
    
    	return (
    		<div
    		className={`${classes.control} ${
    			props.isValid === false ? classes.invalid : ''
    		}`}
    	>
    		<label htmlFor={props.id}>{props.label}</label>
    		<input
    		  ref={inputRef}
    			type={props.type}
    			id={props.id}
    			value={props.value}
    			onChange={props.onChange}
    			onBlur={props.onBlur}
    		/>
    	</div>
    	)

     

     

    - 즉, 컴포넌트 함수는 forwardRef의 첫 번째 인수이다. 그리고 forwardRef는 리액트 컴포넌트를 반환한다.

    - input은 여전히 리액트 컴포넌트지만 ref에 바인딩 될 수 있는 리액트 컴포넌트다.

    - 포커싱 같은 곳에서 현실적으로 사용할 수 있다.

     

    728x90

    댓글

Designed by Tistory.