React는 상태(state)와 속성(props)이라는 두 가지 개념을 중심으로 구성된 JavaScript 라이브러리다.
props 와 state 는 React 에서 데이터를 다룰 때 사용하는 개념이다.
State(상태)
React 컴포넌트에서 state는 컴포넌트 내부에서 관리되는 값으로서 변경 가능하다. 이 값은 컴포넌트가 렌더링되는 동안 변할 수 있으며, 변경될 때마다 컴포넌트가 다시 렌더링된다.
즉, React에서 state는 컴포넌트 내에서 관리되는 상태 데이터이며, 컴포넌트 내부에서 변경할 수 있고, 컴포넌트의 렌더링 결과를 결정한다.
State 사용 방법
1. State 초기화하기
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 }; // state 초기화하기
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
2. State 업데이트하기
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
handleIncrement = () => {
this.setState({ count: this.state.count + 1 }); // state 업데이트하기
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleIncrement}>
Increment
</button>
</div>
);
}
}
3. 비동기적인 State 업데이트하기
setState() 메서드는 비동기적으로 동작한다. 따라서 setState() 메서드를 호출한 직후에는 새로운 상태가 반영되지 않을 수 있다. 이러한 경우에는 setState() 메서드에 콜백 함수를 전달하여 비동기적인 상태 업데이트가 완료된 후에 추가적인 작업을 수행할 수 있다.
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
handleIncrement = () => {
this.setState(
{ count: this.state.count + 1 },
() => console.log('count:', this.state.count) // 비동기적인 State 업데이트하기
);
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.handleIncrement}>
Increment
</button>
</div>
);
}
}
State의 장점
- 컴포넌트의 내부 상태를 유지할 수 있다.
- 동적인 UI를 구성할 수 있다. 예를 들어, 상태 데이터를 사용하여 사용자 입력에 대한 반응을 보여주거나, 외부 API에서 데이터를 가져와서 화면을 업데이트할 수 있다.
- React의 렌더링 성능을 최적화할 수 있습니다. React는 컴포넌트의 상태가 변경될 때만 렌더링을 다시 수행한다. 따라서, 상태 데이터를 사용하여 불필요한 렌더링을 방지할 수 있다.
State의 단점
- State의 관리가 어려울 수 있다.
- State는 컴포넌트에서 사용자 인터페이스의 상태를 관리하는 데 사용되기 때문에, 컴포넌트가 복잡해질수록 state를 관리하기가 어려워진다. 상태가 변경될 때마다 컴포넌트의 렌더링이 다시 일어나므로, 상태가 변경되는 빈도가 높으면 성능 문제가 발생할 수도 있다.
- State가 공유되지 않는다.
- State는 컴포넌트의 내부 상태를 관리하는 데 사용되기 때문에, 컴포넌트 간에 state를 공유할 수 없다. 이는 컴포넌트 간에 데이터를 전달할 때 Props를 사용해야 함을 의미한다.
- State의 중복이 발생할 수 있다.
- 여러 컴포넌트에서 동일한 상태를 사용해야 하는 경우, 상태를 중복해서 사용할 수 있다. 이 경우, 중복된 상태를 업데이트하는 것이 어려울 수 있으며, 이로 인해 코드의 가독성과 유지보수성이 저하될 수 있다.
- State의 불변성을 유지해야 한다
- React에서 state를 변경할 때, 기존 상태 객체를 변경하는 대신 새로운 상태 객체를 생성해야 한다. 이는 state의 불변성을 유지해야 함을 의미한다. 상태의 불변성을 유지하지 않으면 컴포넌트 간에 state가 공유되거나 상태 업데이트가 예기치 않게 발생할 수 있다.
- State의 크기가 커지면 성능 문제가 발생할 수 있다
- 컴포넌트의 state가 매우 큰 경우, 상태 업데이트를 처리하는 데 많은 시간이 소요될 수 있다. 이 경우, 상태를 분할하거나 최적화하는 것이 필요할 수 있다.
Props(속성)
props는 부모 컴포넌트에서 자식 컴포넌트로 데이터가 전달되는 값으로서, 직접적으로 수정할 수 없는 값으로, 읽기 전용이다.
props는 컴포넌트를 불변적으로 만들어주기 때문에, 컴포넌트 간에 데이터를 전달하거나 컴포넌트를 재사용하는 데에 매우 유용하다.
Props는 불변(immutable)하며, 컴포넌트 내에서 수정할 수 없다. Props를 전달하려면 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달해야한다. 자식 컴포넌트에서 Props를 사용할 때는 this.props를 사용하거나 함수형 컴포넌트에서 인자로 전달받는다.
Props 사용 방법
1. Props 사용하기
부모 컴포넌트에서 자식 컴포넌트로 Props를 전달한다.
import React from 'react';
function Greeting(props) { // Props 사용하기
return <h1>Hello, {props.name}!</h1>;
}
function App() {
return <Greeting name="React" />;
}
2. 클래스 컴포넌트에서 Props 사용하기
import React, { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>; // 클래스 컴포넌트에서 Props 사용하기
}
}
class App extends Component {
render() {
return <Greeting name="React" />;
}
}
3. Props의 기본값 설정하기
import React from 'react';
import PropTypes from 'prop-types';
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
Greeting.defaultProps = {
name: 'React' // Props의 기본값 설정하기
};
Greeting.propTypes = {
name: PropTypes.string
};
function App() {
return <Greeting />;
}
4. Props children 사용하기
Props children은 부모 컴포넌트에서 자식 컴포넌트에 전달하는 컴포넌트의 자식 요소다.
import React from 'react';
function Button(props) {
return <button>{props.children}</button>; // Props children 사용하기
}
function App() {
return (
<Button>
Click me
</Button>
);
}
Props의 장점
- 데이터의 일관성을 유지할 수 있다
- 재사용성이 높아진다
- 유지보수가 용이하다
Props의 단점
- Props는 읽기 전용이다
- Props는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 읽기 전용 데이터다. 따라서 자식 컴포넌트에서 props를 변경하려고 하면, React에서 경고 메시지를 표시하며 이를 허용하지 않는다. 이로 인해 컴포넌트 간의 데이터 흐름이 복잡해질 수 있다.
- Props의 전달이 너무 많아질 수 있다
- 부모 컴포넌트에서 자식 컴포넌트로 props를 전달할 때, 컴포넌트의 중첩 수준이 깊어질수록 props의 전달이 너무 많아져서 코드의 가독성이 저하될 수 있다. 이 경우, Redux와 같은 상태 관리 라이브러리를 사용하는 것이 더 나은 방법일 수 있다.
- Props가 공유되지 않는다
- Props는 부모 컴포넌트에서 자식 컴포넌트로 전달되는 데이터이기 때문에, 컴포넌트 간에 props를 공유할 수 없다. 이는 상태를 관리할 때 발생하는 중복 코드 문제와 비슷한 문제를 발생시킬 수 있다.
- Props의 이름 충돌이 발생할 수 있다
- 여러 컴포넌트에서 동일한 이름의 props를 사용하는 경우, props의 이름 충돌이 발생할 수 있다. 이 경우, props의 이름을 변경해야 하거나, 자식 컴포넌트에서 props를 사용하기 전에 props를 검사하고 처리해야 한다.
- Props의 타입 체크가 필요하다
- props는 JavaScript의 동적 타입 시스템을 사용하기 때문에, 부모 컴포넌트에서 전달된 props의 타입이 예상과 다를 수 있다. 따라서, 자식 컴포넌트에서 props의 타입을 검사하고 처리해야 한다. 이를 위해 PropTypes와 같은 타입 체크 라이브러리를 사용할 수 있다.
State와 Props의 차이점
State | Props | |
소유 | 컴포넌트 내부 | 컴포넌트 외부 |
변경 가능성 | 변경 가능 | 읽기 전용 |
데이터 전달 방식 | 컴포넌트 내부에서 처리 | 부모 컴포넌트에서 자식 컴포넌트로 전달 |
범위 | 컴포넌트 내부 | 컴포넌트 내부와 외부 모두 |
초기값 설정 | constructor 메소드 내부에서 설정 | 부모 컴포넌트에서 전달 |
출처
https://ko.reactjs.org/docs/faq-state.html
https://github.com/uberVU/react-guide/blob/master/props-vs-state.md
https://lucybain.com/blog/2016/react-state-vs-pros/
https://minjung-jeon.github.io/React-props-state/
https://ko.reactjs.org/docs/components-and-props.html
https://ko.reactjs.org/docs/state-and-lifecycle.html
https://ko.reactjs.org/docs/typechecking-with-proptypes.html
https://velog.io/@chloeee/state-상태-Props-속성
'기술 개발 > React' 카테고리의 다른 글
날짜 라이브러리 비교(Day.js, Moment.js, date-fns, Luxon) (0) | 2023.02.10 |
---|---|
Data Fetching Library: React-Query, SWR (0) | 2023.01.31 |
컴포넌트 성능 최적화 (0) | 2023.01.10 |
React hooks (useRef) (0) | 2023.01.08 |
React hooks (useCallback) (0) | 2023.01.08 |