JSX (JavaScript XML)
자바스크립트에 XML을 추가한 확장형 문법이다.
하나의 파일에 자바스크립트와 HTML 동시에 작성이 가능하다.
리액트 엔진은 JSX의 XML구조를 분석하여 자바스크립트 함수코드로 변환한다.
*리액트 앱 구동시켜 웹 브라우저에서 확인 가능
(오류도 웹에서 바로 확인 가능)
컴포넌트
기존의 웹 프레임 워크는 MVC방식으로 정보 (Model), 화면(View) , 구동(Controller) 코드를 분리하여 관리하였으나
MVC 각 요소의 의존성이 높은 탓에 재활용이 어려웠다.
컴포넌트가 등장하여 MVC의 뷰를 독립적으로 구성하고 재활용할 수 있게 되었다.
이는 각 요소가 비슷하고 반복적으로 사용하는 경우가 많은 웹사이트에 더 적합한 방식이다.
컴포넌트는 프로퍼티 / state / 컨텍스트로 구성되어있다.
구성 요소 1. 프로퍼티
상위 컴포넌트에서 하위 컴포넌트로 전달되는 읽기 전용 데이터로 값을 수정할 수 없다.
↓상위 컴포넌트인 App컴포넌트에서 프로퍼티를 하위 컴포넌트인 MyComponent컴포넌트에 전달하는 예제
class App extends React.Component {
render() {
return (
<div className="body">
<MyComponent name="message"/> //프로퍼티는 속성 형태로 전달
</div>
);
}
}
class MyComponent extends React.Component {
render(){
const name = this.props.name; //this.props.name으로 프로퍼티 값 참조
return <span>{name}</span>;
}
}
프로퍼티의 자료형은 미리 선언하는 것이 좋다.
불리언 프로퍼티는 true의 경우 프로퍼티의 이름만 선언하고 false의 경우 이름을 생략하는 형태로 값을 전달할 수 있다.
객체형 프로퍼티로 여러 값을 저장하여 전달할 수 있다.
꼭 전달되어야 하는 프로퍼티는 필수 프로퍼티로 지정한다.
↓ 객체형 프로퍼티와 필수 프로퍼티를 사용한 하위 컴포넌트 예제
import React from 'react';
import PropTypes from 'prop-types';
class ChildComponent2 extends React.Component {
render() {
const { objValue, requiredStringValue } = this.props;
return (
<div>
<div>객체값: {String(Object.entries(objValue))}</div> //객체를 문자열로 변환하여 출력
<div>필수값: {requiredStringValue}</div>
</div>
);
}
}
ChildComponent2.propTypes = {
//객체 프로퍼티 (PropTypes의 shape를 사용하여 정의)
objValue: PropTypes.shape({
name: PropTypes.string,
age: PropTypes.number
}),
//필수 프로퍼티 (특수 변수 isRequired를 이용하여 필수 프로퍼티로 지정)
requiredStringValue: PropTypes.string.isRequired
};
프로퍼티에 기본값을 지정하고 싶다면 특수변수인 defaultProps를 사용하여 프로퍼티의 기본값을 정의한다.
상위 프로퍼티에 자식노드를 배치한 경우 하위 컴포넌트에서는 {this.props.children}과 같은 방법으로 자식노드를 받을 수 있다.
구성 요소 2. state
컴포넌트의 상태를 저장하고 변경할 수 있는 데이터로 보통 버튼을 클릭하거나 값을 입력하는 등의 이벤트와 사용된다.
import React from 'react';
class StateExample extends React.Component {
constructor(props) {
super(props);
//state의 초깃값을 this.state에 객체 형태로 정의
this.state = {
loading: true,
formData: 'no data'
};
this.handleData = this.handleData.bind(this); //함수로 넘어갈 this는 반드시 bind()로 묶어줘야함
setTimeout(this.handleData, 4000); //4초후 handleData()함수 호출
}
handleData() {
const data = 'new data';
const {formData} = this.state;
//state변경
this.setState({
loading: false,
formData: data + formData,
});
//this.state.loading은 현재 true
//이후 호출될 render()함수에서의 this.state.loading은 false
}
render() {
return (
<div>
{/*state데이터는 this.state로 접근 가능*/}
<span>로딩중 : {String(this.state.loading}</span>
<span>결과 : {this.state.formData}</span>
</div>
);
}
}
}
export default StateExample;
state를 사용할 때 주의할 점
1. 생성자에서 반드시 초기화해야 한다.
=> 초기화하지 않으면 내부 함수에서 state값에 접근할 수 없다. 초깃값이 없다면 빈 객체라도 넣어야 한다.
2. state값을 변경할 때는 setState()함수(상태관리함수)를 반드시 사용해야 한다.
=>setState()함수로 호출하여 state값을 변경하면 리액트 엔진이 자동으로 render()함수를 호출하여 변경된 state값을 새롭게 출력해주기 때문이다. render()함수를 새로 호출하지 않으면 새로운 화면을 그려주지 않는다.
3. setState()함수는 비동기로 처리되며, setState()코드 이후로 연결된 함수들의 실행이 완료된 시점에 화면 동기화 과정을 거친다.
=>따라서 setState()함수의 인자로 함수를 전달하면 이전 state값을 따로 읽는 과정을 생략할 수 있다.
출력 검증 작업없이 함수가 호출될 때마다 새롭게 화면을 출력하고 싶다면,
클래스 인스턴스 변수 & forceUpdate() (화면을 강제로 출력해주는 함수)를 사용한다.
(코드 작성.......)
구성 요소 3. 컨텍스트
부모 컴포넌트에서 생성하여 모든 자식 컴포넌트에 전달하는 데이터
(6장에서 설명...)
컴포넌트의 생명주기
컴포넌트의 생성부터 소멸까지의 과정을 생명주기라고 한다.
생명주기마다 함수를 가지고 있는데 이 생명주기 함수는 리액트 엔진에서 자동으로 호출된다.
constructor(props) 함수
- 상태를 선언할 때 사용되며 맨 처음에 생성될 때 한 번만 호출된다.
- 항상 super()함수를 가장 위에 호출해야 한다.
render() 함수
- 데이터가 변경되어 새 화면을 그려야 할 때 자동으로 호출된다.
static getDerivedStateFromProps(props, state) 함수
- 상위 컴포넌트에서 전달받은 프로퍼티로 state값을 연동할 때 주로 사용된다.
- 반환값으로 state를 변경한다.
componentDidMount()함수
- 컴포넌트가 화면에 모두 표현된 이후에 하는 작업들을 다룬다.
shouldComponentUpdate(nextProps, nextState)함수
- 프로퍼티를 변경하거나 setState함수를 호출하여 state값을 변경할 때 화면을 새로 출력할 지 판단한다.
getSnapshotBeforeUpdate(prevProps, prevState)함수
- 컴포넌트의 변경된 내용이 가상화면에 완성된 이후 호출된다.
- 스크롤 위치 등의 DOM정보에 접근할 때 사용된다.
componentDidUpdate(prevProps, prevState, snapshot)함수
- 컴포넌트가 실제 화면에 출력된 이후 호출된다.
- 스크롤 위치를 옮기는 등의 DOM정보를 변경할 때 사용된다.
componentWillUnmount()함수
- 컴포넌트가 소멸되기 직전에 호출된다.
- 컴포넌트에서 감시하고 있는 작업들을 해제할 때 사용된다.
클래스형 컴포넌트
Component 클래스
- 프로퍼티, state와 생명주기 함수가 들어있는 구조의 컴포넌트를 만들 때 사용한다.
PureComponent 클래스
- Component 클래스를 상속받은 클래스이다.
- 얕은 비교를 통해 데이터가 변경된 경우에만 render()함수를 호출한다.
- 얕은 비교를 위해 shallowEqual()함수를 사용한다.
*얕은 비교란
요소 하나하나를 비교해보는 것이 아니기 때문에 새롭게 정의된 배열이어도 같은 요소를 가지고 있는 경우엔 비굣값이 true가 나올 수 있다..
함수형 컴포넌트
함수형 컴포넌트는 state를 포함하지 않고 데이터를 받아 출력할 컴포넌트를 반환한다.
클래스 선언 없이 프로퍼티와 컨텍스트만을 사용하여 화면을 구성한다.
생명주기 함수도 쓸 수 없다.
-> 간단한 구조의 UI컴포넌트에 주로 사용된다.
배열 컴포넌트
쓰기 귀차나,,,,,,,,,,
콜백함수와 이벤트 처리
하위 컴포넌트에서 프로퍼티를 변경할 때
=> 프로퍼티 원본을 수정할 수 있는 함수를 하위 컴포넌트에 제공한다. = 콜백함수를 프로퍼티로 전달한다.
'Tech > ReactJS' 카테고리의 다른 글
[React] 다중 하이어오더 컴포넌트 (0) | 2021.07.16 |
---|---|
[React] 하이어오더 컴포넌트 라이브러리 (0) | 2021.07.16 |
[React] 하이어오더 컴포넌트 개념 (0) | 2021.07.16 |
[React] 커링함수와 함수 조합 기법 (0) | 2021.07.16 |
[React] 리액트와 ES6문법 정리 (0) | 2021.07.14 |