Props와 State (23.09.06-07)

·2023년 9월 6일
0

React

목록 보기
3/30
post-thumbnail

💡 Props

  • React 컴포넌트에게 데이터를 전달하는 방법 중 하나
  • 부모 컴포넌트로부터 자식 컴포넌트로 전달되며, 컴포넌트 내부에서 변경할 수 없는 읽기 전용 데이터

👍 Props의 장점

  • 컴포넌트 간의 데이터 전달이 간단하고 유지보수하기 쉬워짐
  • 컴포넌트의 재사용성을 높일 수 있음

📁 Props Drilling

(상태 내리꽂기)
Props를 통해 데이터를 전달할 때, 하위 컴포넌트에서 필요하지 않은 Props를 계속해서 전달하는 것

Props Drilling은 코드의 가독성을 떨어뜨리고, 유지보수를 어렵게 만들 수 있다.
따라서 Props drilling을 최소화하기 위해서는 필요한 Props만을 전달하고, 필요하지 않은 Props는 하위 컴포넌트에서 직접 접근하는 것이 좋다.

이를 위해서는 React Context나 Redux와 같은 상태 관리 라이브러리를 사용하는 것도 좋은 방법이다.

👀 코드로 살펴보기

R01_props.js

import React from 'react';

// props : 부모 컴포넌트가 자식 컴포넌트에게
//         데이터 전달 시 사용하는 객체
// *** props는 자식 -> 부모 데이터 전달은 불가능 ***

const ChildComponent = (props) => {
    return(
        <>
            <ul>
                <li>이름 : {props.name}</li>
                <li>나이 : {props.age}</li>
            </ul>
        </>
    );
}

const MenuPrint = (props) => {
    return(
        <h4>김밥 : {props.김밥}, 떡볶이 : {props.떡볶이}</h4>
    );
}

const PropsEx = (props) => {
    // props 매개변수 : 부모로부터 전달받은 값이 담겨 있는 객체

    console.log(props);
    console.log(props.name);

    const menu = {'김밥':3000, '떡볶이':4000};

    return(
        <>
            <h1>{props.name}</h1>
            <ChildComponent name={props.name} age={props.name === '홍길동' ? 20 : 25}/>
            <MenuPrint {...menu}/>
            {/* <MenuPrint 김밥={3000}, 떡볶이={4000} */}
        </>
    );

}

export default PropsEx;

App.js

import './App.css';

import PropsEx from './components/R01_props';

function App() {

  return (

    <>
      {/* jsx 주석 */}
      <h1>Hello React!!!</h1>
  
      <div>리액트 배운다~</div>

      <PropsEx name={'홍길동'}/>
      <PropsEx name={'김길동'}/>
      <PropsEx name={'이길동'}/>

    </>
  );
}

export default App;

💻 구현 화면


💡 State

  • 컴포넌트 내부에서 관리되는 상태 값
  • 컴포넌트가 생성되고, 갱신될 때마다 변경될 수 있는 값

state는 useState Hook을 사용하여 컴포넌트 내부에서 관리할 수 있으며, setState 함
수를 통해 값을 업데이트할 수 있다.

React에서의 state는 컴포넌트의 상태를 저장하고, 필요에 따라 다시 렌더링하는 데 사용된다. 사용자 인터랙션에 따라 컴포넌트 내의 상태가 변경되면, React는 이를 감지하고 변경
된 상태를 바탕으로 화면을 다시 렌더링한다. 이를 통해 동적으로 변하는 UI를 만들 수 있다.

👀 코드로 살펴보기

R02_state1

import React, {useState} from "react";

// 컴포넌트 이름은 대문자!

// 리액트는 컴포넌트의 상태가 변할 때마다 리렌더링을 수행함
const InputTest =  () => {

    const [inputValue, setInputValue] = useState("초기값");
    //        변수           함수         
    // inputValue : 값을 저장하는 변수
    // setInputValue : inputValue에 값을 대입하는 setter 역할의 함수

    const changeInputValue = (e) => {
        console.log(e.target.value);
        setInputValue(e.target.value);
        
    }

    return(

        // 첫 렌더링 : value = "초기값"
        // -> input의 값을 변경
        //    1) onChange(값이 변했을 때)
        //     -> changeInputValue 함수가 실행되면서
        //        inputValue에 e.target.value(변화된 값을 대입)

        //    2) 컴포넌트의 상태 변화 -> 리렌더링 진행

        // 리렌더링 -> value = 변경된 inputValue의 값

        <input type="text" value={inputValue}
            onChange={changeInputValue}/>
        // onChange={(e) => {setInputValue(e.target.value)}}/>
        );      
}

export default InputTest;

R03_state2

import React, {useState} from "react";

const State2 = (props) => {

    // props : 부모로부터 전달받은 값을 저장한 객체
    // props.init

    // const [count, setCount] = useState(0);
    const [count, setCount] = useState(props.init);
    // useState : 컴포넌트의 상태를 관리할 때 사용하는 Hook
    // const [변수, 값을 변경하는 함수(setter)] = useState(초기값);

    return(
        <div>
            <h3>{count}</h3>
            <button onClick={() => setCount(count + 1)}>클릭하면 Count 1 증가</button>
        </div>
    );

}

export default State2;

App.js

import './App.css';

import State1 from './components/R02_state1';
import State2 from './components/R03_state2';


function App() {

  return (

    <>
      {/* jsx 주석 */}
      <h1>Hello React!!!</h1>
  
      <div>리액트 배운다~</div>

      {/* R02_state1 */}
      <State1 />

      {/* R03_state2 */}
      <State2 init={100} />

    </>
  );
}

export default App;

💻 구현 화면


📁 State lifting up

(상태 끌어올리기)
하위 컴포넌트에서 발생한 이벤트를 상위 컴포넌트에서 처리하도록 하는 것

👀 코드로 살펴보기

R04_state3

import React, {useState} from 'react';

const Id = ({handler}) => {

    // props로 전달한 값 중 key가 handler인 요소의 value 반환
    // console.log(handler);

    return(
        <>
            <div className='wrapper'>
                <label htmlFor='id'>ID : </label>
                <input type='text' id='id' onChange={handler}/>
            </div>
        </>
    );
};

const Pw = ({handler}) => {
    return(
        <>
            <div className='wrapper'>
                <label htmlFor='pw'>PW : </label>
                <input type='password' id='pw' onChange={handler}/>
            </div>
        </>
    );
};

// 상태 끌어올리기
const StateLiftingUp = () => {

    const [id, setId] = useState('');
    const [pw, setPw] = useState('');

    const idHandler = (e) => { // id 값을 변경하는 함수
        setId(e.target.value);
    };

    const pwHandler = (e) => { // pw 값을 변경하는 함수
        setPw(e.target.value);
    };

    console.log("id : " + id);
    console.log("pw : " + pw);

    return(
        <>
            <Id handler={idHandler}/>
            <Pw handler={pwHandler}/>

            <div className='wrapper'>
                <button disabled={id.length === 0 || pw.length === 0 }>Login</button>
            </div>
        </>
    );
};

export default StateLiftingUp;

💻 구현 화면

profile
풀스택 개발자 기록집 📁

0개의 댓글