props는 외부로부터 전달받은 값.
state는 내부에서 변화하는 값.
컴포넌트의 속성(property)을 의미함.
props는 성별이나 이름처럼 변하지 않는 외부로부터 전달받은 값임.
부모 컴포넌트(상위 컴포넌트)로부터 전달받은 값임.
React 컴포넌트는 JavaScript 함수와 클래스로, props를 함수의 전달인자(arguments)처럼 전달받음. 따라서, 컴포넌트가 최초 렌더링될 때에 화면에 출력하고자 하는 데이터를 담은 초기값으로 사용할 수 있습니다.
객체 형태임.
props는 읽기 전용임.
함부로 변경되지 않아야 하기 때문임.
여는 태그와 닫는 태그의 사이에 value 를 넣어 전달할 수 있음.
이 경우 props.children 을 이용하면 해당 value 에 접근하여 사용할 수 있음.
function Parent() {
return (
<div className="parent">
<h1>I'm the parent</h1>
<Child>I'm the eldest child</Child>
</div>
);
};
function Child(props) {
return (
<div className="child">
<p>{props.children}</p>
</div>
);
};
--구조분해할당 이용 -->
function Child({children}) {
return (
<div className="child">
<p>{children}</p>
</div>
);
};
import { useState } from "react";
useState(
state의 초기값
) --배열을 리턴--> [현재 state 변수
,state 갱신 함수
]
const [state 저장 변수, state 갱신 함수] = useState(상태 초기 값);
state 갱신 함수에 갱신할 값을 전달하면 state 값이 변경되고, 리렌더링됨.
※주의점※
state 값이 갱신되지 않으면 리렌더링 되지않음!
React state는 상태 변경 함수 호출로 변경해야 함. 강제로 변경을 시도하면 안 됨. 강제로 변경을 시도하면, 리렌더링이 되지 않는다거나, state가 제대로 변경되지 않음.
예시 : state.push(1);, state[1] = 2;, state = 'wrong state';
React의 이벤트 처리(이벤트 핸들링; Event handling) 방식은 DOM의 이벤트 처리 방식과 유사하지만, 몇 가지 문법 차이가 있음.
- React 에서 이벤트는 소문자 대신 카멜 케이스(camelCase) 를 사용함.
- JSX를 사용하여 문자열이 아닌 함수로 이벤트 처리 함수(Event handler)를 전달함.
예를 들어 HTML에서 이벤트 처리 방식이 아래와 같다면,
<button>Event</button>
React의 이벤트 처리 방식은 아래와 같음.
<button onClick={handleEvent}>Event</button>
<input> <textarea> <select>
와 같은 폼(Form) 엘리먼트에서 사용자의 입력값은 변경될 수 있기에 react에서는 일반적으로 컴포넌트의 state로 관리하고 업데이트함.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<h1>{name}</h1>
</div>
)
};
onClick 이벤트는 사용자가 클릭이라는 행동을 하였을 때 발생하는 이벤트임.
function NameForm() {
const [name, setName] = useState("");
const handleChange = (e) => {
setName(e.target.value);
}
return (
<div>
<input type="text" value={name} onChange={handleChange}></input>
<button onClick={alert(name)}>Button</button> (X)
<h1>{name}</h1>
</div>
);
};
위와 같이 onClick 이벤트에 alert(name) 함수를 바로 호출하면 컴포넌트가 렌더링될 때 함수 자체가 아닌 함수 호출의 결과가 onClick에 적용됨.
때문에 버튼을 클릭할 때가 아닌, 컴포넌트가 렌더링될 때에 alert 이 실행되고 따라서 그 결과인 undefined (함수는 리턴값이 없을 때 undefined 를 반환함.)가 onClick 에 적용되어 클릭했을 때 아무런 결과도 일어나지 않음(alert 작동 X).
따라서 onClick 이벤트에 함수를 전달할 때는 함수를 호출하는 것이 아니라 아래와 같이 리턴문 안에서 함수를 정의하거나 리턴문 외부에서 함수를 정의 후 이벤트에 함수 자체를 전달해야 함.
<button onClick={() => alert(name)}>Button</button>
또는
const handleClick = () => { alert(name); };
<button onClick={handleClick}>Button</button>
단, 두 가지 방법 모두 arrow function 을 사용하여 함수를 정의하여야 해당 컴포넌트가 가진 state에 함수들이 접근할 수 있음.
React의 개발 방식의 가장 큰 특징은 상향식(bottom-up)으로 앱을 만든다는 거임. 따라서 테스트가 쉽고 확장성이 좋음.
컴포넌트는 컴포넌트 바깥에서 props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받을 수 있음.
즉 데이터를 전달하는 주체는 부모 컴포넌트가 됨.
이는 데이터 흐름이 하향식(top-down)임을 의미함.
" React는 단방향 데이터 흐름(one-way data flow)을 따름. "
모든 데이터를 상태로 둘 필요는 없음. 사실 상태는 최소화하는 것이 가장 좋음.
하나의 상태를 기반으로 두 컴포넌트가 영향을 받는다면 공통 소유 컴포넌트를 찾아 그 곳에 상태를 위치해야 함.
const Hello = (props) => <div>{props.name}</div>
위와 같이 구현한 Hello 컴포넌트가 있는데, name이라는 props를 전달하는 방법들은 다음과 같다.