09_React_240604(화)_96일차(0) - React - State & Props

soowagger·2024년 6월 4일

9_React

목록 보기
2/5

1. State lifting up : 상태 끌어올리기

💡 JSX 작성 시 유의사항

  • JSX를 사용한 HTML 구문 작성부는 무조건 최상위 부모태그 하나로 감싸져 있어야 한다.
  • 빈태그 <> 가능
// State & Props

import { useState } from "react"

// State lifting up : 상태 끌어올리기
// - 리액트는 부모 컴포넌트가 자식 컴포넌트 상태 변경 불가
// -> 자식에서 발생한 이벤트를 부모에서 처리하도록 하는 상태 끌어올리기 패턴을 이용함



// 해당 파일에서 컴포넌트 총 3개 존재
// Id 컴포넌트(자식)
// Pw 컴포넌트(자식)
// Exam3 컴포넌트(부모) = 해당 파일에서 내보낼 기본 컴포넌트


// Id 컴포넌트(자식)
const Id = (props) => { // 부모에게서 전달받은 속성을 props라고 부름

    // *props 꺼내기
    const {onChangeId} = props; // props 안에 있는 onChangeId라는 이름의 함수를 이용할 수 있게 됨

    //const [id, setId] = useState(""); // 상태(state) 중 'id'를 생성하고 초기값 "" 설정

    return (
        // JSX를 사용한 HTML 구문 작성부는 무조건 최상위 부모태그 하나로 감싸져 있어야 한다.
        <>
            <div>
                <label>ID : </label>
                <input onChange={onChangeId} />
                {/* onChange 이벤트에 props 연결 */}
            </div>
        </>
    );

}

// Pw 컴포넌트(자식)
const Pw = ({onChangePw}) => {
            // {} 이용하여 props를 바로 꺼내 쓸 수 있음
    
    //const [pw, setPw] = useState(""); // 상태(state) 중 'pw'를 생성하고 초기값 "" 설정

    return (
        // JSX를 사용한 HTML 구문 작성부는 무조건 최상위 부모태그 하나로 감싸져 있어야 한다.
        <>
            <div>
                <label>PW : </label>
                <input onChange={onChangePw}/>
            </div>
        </>
    );

}


// Exam3 컴포넌트(부모)
const Exam3 = () => {

    // 자식의 상태를 부모에서 정의(상태 끌어올리기)
    const [id, setId] = useState("");
    const [pw, setPw] = useState("");

    // 자식의 상태를 변경할 수 있는 함수 정의
    const onChangeId = e => {
        setId(e.target.value);
    }

    const onChangePw = e=> {
        setPw(e.target.value);
    }

    return(
        <>
            {/* 컴포넌트 중 Id를 불러 렌더링 (Id가 Exam3의 자식이 됨)*/}
            <Id onChangeId={onChangeId}/>
            {/* props */}

            {/* 컴포넌트 중 Id를 불러 렌더링 (Pw가 Exam3의 자식이 됨)*/}
            <Pw onChangePw={onChangePw}/>

            <div>
                {/* button의 disabled 속성 : 비활성화 속성 (비활성 true / 활성 false) 
                    -> id와 pw 둘 다 작성되어야 활성화
                */}
                <button disabled={id.length === 0 || pw.length === 0}>Login</button>
            </div>
        </>
    );

}

export default Exam3;


2. Props Drilling : 상태 내리꽂기

// State & Props

import { useState } from "react";

// Props Drilling : 상태 내리꽂기 
// - props를 통해 데이터를 전달할 때, 자식 컴포넌트에서 필요하지 않은 props를 계속해서 전달하는 행위
// - 코드의 가독성 및 유지보수성 저하
// -> React Context API, Redux 같은 상태 관리 라이브러리를 사용함

// Exam4 > Child1 > Child2 > Child3 > MyComponent 부모자식 관계 연결
// Exam4의 상태값을 MyComponent에서 사용해야 한다면?

// 부모 컴포넌트
function Exam4() {
    const [name, setName] = useState("홍길동");


    const handleClick = () => {
        setName("고길동");
    }

    return (
        <>
            <Child1 name={name} />
            <button onClick={handleClick}>이름 변경</button>
        </>
    );
}


function Child1(props) {
    return <Child2 name={props.name} />
}

function Child2(props) {
    return <Child3 name={props.name} />
}

function Child3(props) {
    return <MyComponent name={props.name} />
}

function MyComponent(props) {
    // props는 Exam4에서부터 내리꽂기를 통해 전달받은 부모의 상태값
    
    return <h1>{props.name}</h1>
}


export default Exam4;

3. 전개 연산자

// props 응용
// 전개 연산자 (...) : 객체 내부의 모든 값을 props로 전달하는 방법

import { useState } from "react";

// 부모
function Exam5() {
    const [userData, setUserData] = useState( {name : '홍길동', age : 30} );

    //return <MyComponent name={userData.name} age={userData.age} />
    return <MyComponent {...userData} />
    
}


// 자식
function MyComponent(props) {
    const { name, age } = props;

    const content = `안녕하세요, 제 이름은 ${name}이고, 나이는 ${age}세입니다.`;
    return <h3>{content}</h3>
}


export default Exam5;

profile

0개의 댓글