React(0913)

GW·2023년 9월 13일

contact

Literal Style

------------------------------------------------------InlineBox.js
export default function InlineBox({bgColor,letter}){
    const style={
        padding:"10px",
        margin:"10px",
        backgroundColor:bgColor,
        color:"#333",
        display:"inline-block",
        fontSize:"50px",
        fontFamily:"맑은 고딕",
        textAlign:"center"
    }
    return(
        <div style={style}>{letter}</div>       
    );
}
------------------------------------------------------InlineApp.js
import InlineBox from "./InlineBox";

export default function InlineApp(){
    return(
        <div>
            <InlineBox letter="A" bgColor="#EEE"/>
            <InlineBox letter="E" bgColor="#CCC"/>
            <InlineBox letter="I" bgColor="#AAA"/>
            <InlineBox letter="O" bgColor="#999"/>
            <InlineBox letter="U" bgColor="#888"/>
        </div>
    );
}

라이프 사이클 개요

  • 클래스 컴포넌트는 여러 종류의 라이프사이클 메소드를 제공한다
  • React 에서 제공하는 라이프사이클 메소드를 재정의 해
    특정 시점에 코드가 실행되도록 할 수 있다
  • React Hook 으로 간접 사용할 수 있게 되었다
    • 함수형 컴포넌트는 라이프사이클을 사용할 수 없다
  • React 가 제어할 수 없는 부작용 (Side effect) 를 처리 하기 위해 사용됨
  • DOM Handling ( 실제 문서) 에 접근 및 조작
  • 네트워크 통신 비동기 통신 요청 및 응답 처리
    • Fetch API 또는 axios 라이브러리
  • 이벤트 핸들린 작업에서 구독 및 취소 작업
    • 컴포넌트 생성시점에 이벤트 구독했으면 , 제거시점에 이벤트
      를 취소해야함

컴포넌트의 라이프 사이클

렌더링 전 후 마운트 상태

constructor

  • 새로운 객체가 생성될 때 마다 실행
  • this.props 초기화 가능 , this.setState 또는 Ajax 등의 처리 불가
    static getDerivedStateFromProps
  • 컴포넌트 초기화 또는 새로운 props 를 받았을 때 실행
  • this 키워드는 사용할 수 없음

render

  • 화면에 컴포넌트를 작성
  • this.props 와 this.state 를 분석 후 화면에 노출
  • state 를 변경할 수 없으며 , 브라우저 API 에 직접 접근 불가

componentDidMount

  • 컴포넌트 렌더링이 완료되었을 때 실행
  • DOM 에 접근이 가능하며 , Ajax 및 데이터 로직 처리에 적합

수정 전 후 업데이트 상태

shouldComponentUpdate (nextProps, nextState) {}

  • state 가 변경 될 경우 shouldComponentUpdate 부터 라이프사
    이클 진행

getSnapshotBeforeUpdate (prevProps, prevState) {}

  • render 메서드 호출 후 DOM 에 변화를 반영하기 바로 전에 호
  • 이 메서드에서 리턴된 값 을 componentDidUpdate 메서드의 세
    번째 파라미터 snapshot ) 에서 받을 수 있다
  • 주로 업데이트하기 직전의 값을 참고할 때 사용 된다

componentDidUpdate (prevProps, prevState, snapshot) {}

  • 모든 re rendering 이 완료된 후 호출
  • DOM 처리 가능
  • prevProps, prevState 값을 이용해 컴포넌트의 이전 데이터에 접
    근할 수 있다

함수형 컴포넌트를 위한 React Hooks

useState

  • State 값 관리를 위한 Hook
  • 함수형 컴포넌트로 state 관리 가능 (React 16.8 에서 Hook 도입

const [number, setNumber] = useState(0);

  • number: state 의 이름
  • setNumber: number state 값 변경함수
  • 호출 후 값이 변경되었다면 컴포넌트를 Re Rendering 한다
  • 0: number state 의 기본 값

useRef

  • 특정 DOM 에 접근하기 위한 Hook
  • jQuery 는 브라우저의 DOM 을 직접제어함
  • 속도가 느리다.
---------------------------------------------------------------UseRefTest
import { useRef } from "react";

export default function RefComponent(){

    const nameRef = useRef()
    function click(){
        const nameInput=nameRef.current // current는 Ref가 연결되어있는 태그
        console.log(nameInput)
        console.dir(nameInput)
        console.log(nameInput.dataset["name"])
        console.log(nameInput.value)
        if(nameInput.value==""){
            alert("이름을 입력하세요")
            nameInput.value="이름은 필수값 입니다."
            nameInput.focus()
        }
    }
    return(
        <div>
            <input  data-name="111" ref={nameRef}/>
            <button onClick={click}>클릭!</button>
        </div>
    );
}

MemberList useRef로 바꾸기

import { useRef, useState } from "react";

export default function MemberList(){
    const [memberData, setMembertData]= useState([]);
    const nameRef=useRef()
    const ageRef=useRef()
    const addressRef=useRef()

    function save(){
        const nameInput=nameRef.current
        const ageInput=ageRef.current
        const addressInput=addressRef.current
        let data=[...memberData]
        data.push({username:nameInput.value, age:ageInput.value, address:addressInput.value});
        setMembertData(data);

    }

    return(
        <div>
           <div>
                <label htmlFor="name">이름</label>
                <input  type="text" id="name" ref={nameRef}/>
            </div>
            <div>
                <label htmlFor="age">나이</label>
                <input  type="text" id="age" ref={ageRef}/>
             </div>
            <div>
                <label htmlFor="address">주소</label>
                <input  type="text" id="address" ref={addressRef}/>
            </div>
            <div>
                <button onClick={()=>save()}>저장</button>
            </div>
            <Member memberData={memberData}/>
        </div>
    );
}
function Member({memberData}){
    return(
        <>
        {
            memberData.map((value,index)=>
                    <div key={index}>
                        <span>{value.username}</span>
                        <span>{value.age}</span>
                        <span>{value.address}</span>
                    </div>)
        }
        </>
    );
}

useRef를 Props로 보낼려면 forwardRef가 필요하다

useEffect

----------------------------------------------------------------------------------------------userEffectTest.js
import { useEffect, useState } from "react";

export default function EffectComponent(){

    const [memberData, setMembertData]=useState([])
    const [name,setName]=useState("")
    const [age,setAge]=useState("")
    const [address,setAddress]=useState("")

    useEffect(()=>{
        console.log(`이함수는 props 또는 state중 하나라도 변경이 된다면 무조건 실행하는 함수입니다.`)
        
    })//의존배열 파라미터가 없다면 컴포넌트가 갱신될때마다 실행된다.
      // Lifecycle: componentDidMount, componentDidUpdate
    useEffect(()=>{
        console.log(`이 함수는 컴포넌트가 처음으로 만들어질 때에만 실행되는 함수입니다.`)
    },[]) //의존 배열 파라미터가 []라면 컴포넌트가 만들어 질 때에만 실행된다.
          // Lifecycle : componentDidMount
    useEffect(()=>{
        console.log(`이함수는 컴포넌트의 name state가 변경되었을 때에만 실행되는 함수입니다.`)
    },[name])//Lifecycle : componentDidUpdate
             // 쿠팡이 react로 만들었다면 카테고리
    useEffect(()=>{
        console.log(`이 함수는 컴포넌트의 age,address, memberData state중 하나라도 변경이 되었을때 실행되는 함수입니다.`)
    },[age,address,memberData])//Lifecycle : componentDidUpdate


    function changeName(){
        setName(Math.random())
    }
    function changeAge(){
        setAge(Math.random())
    }
    function changeAddress(){
        setAddress(Math.random())
    }
    function changeMemberData(){
        let data=[...memberData]
        data.push({name,age,address})
        setMembertData(data)
    }

    return (
        <div>
            <button onClick={changeName}>이름 변경하기</button>
            <button onClick={changeAge}>나이 변경하기</button>
            <button onClick={changeAddress}>주소 변경하기</button>
            <button onClick={changeMemberData}>목록 변경하기</button>
        </div>
    );
}

useReducer - 상태를 관리하기 위한 또 다른 방법

  • useState 처럼 state 를 생성하고 관리할 수 있도록 하는 hook
  • 복잡한 형태의 객체를 상태로 관리할 때 유용

useReducer 를 사용하기 위한 기본 지식 3 가지

Reducer

  • state 를 대신 update 하는 역할

Dispatch

  • Reducer 에게 update 를 요청하는 역할

Action

  • Dispatch 에 전달할 내용
    • 예 > 예금 , 송금 , 출금 등

0개의 댓글