- React 컴포넌트에게 데이터를 전달하는 방법 중 하나
부모 컴포넌트
로부터자식 컴포넌트
로 전달되며, 컴포넌트 내부에서 변경할 수 없는 읽기 전용 데이터
(상태 내리꽂기)
Props를 통해 데이터를 전달할 때, 하위 컴포넌트에서 필요하지 않은 Props를 계속해서 전달하는 것
Props Drilling은 코드의 가독성을 떨어뜨리고, 유지보수를 어렵게 만들 수 있다.
따라서 Props drilling을 최소화하기 위해서는 필요한 Props만을 전달하고, 필요하지 않은 Props는 하위 컴포넌트에서 직접 접근하는 것이 좋다.
이를 위해서는 React Context나 Redux와 같은 상태 관리 라이브러리를 사용하는 것도 좋은 방법이다.
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;
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는 useState Hook을 사용하여 컴포넌트 내부에서 관리할 수 있으며, setState 함
수를 통해 값을 업데이트할 수 있다.
React에서의 state는 컴포넌트의 상태를 저장하고, 필요에 따라 다시 렌더링하는 데 사용된다. 사용자 인터랙션에 따라 컴포넌트 내의 상태가 변경되면, React는 이를 감지하고 변경
된 상태를 바탕으로 화면을 다시 렌더링한다. 이를 통해 동적으로 변하는 UI를 만들 수 있다.
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;
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;
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;
(상태 끌어올리기)
하위 컴포넌트에서 발생한 이벤트를 상위 컴포넌트에서 처리하도록 하는 것
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;