fffo
React doc 정리 본문
JSX
- 리액트는 렌더링 로직과 UI로직이 본질적으로 연결된다는 사실을 받아들임
- 전통적 웹은 각기 다른 파일에 마크업과 로직을 분리해 관리했지만 리엑트는 둘을 모두 포함하는 ‘컴포넌트’로 관심사를 분리함
- JSX도 표현식임
- 컴파일 후 JSX 표현식이 js 객체로 인식됨
- JSX는 insection attack을 방지함
- ReactDOM이 JSX에 삽입된 모든 값을 렌더링하기 전에 escape하므로 앱에 명시적으로 작성되지 않은 내용은 주입되지 않음
- 모든 항목은 렌더링 되기 전에 문자열로 변환됨
- XSS(cross-site-scripting) 공격 방지 가능
Element Rendering
- 엘리먼트는 React 앱의 가장 작은 단위
- 엘리먼트는 컴포넌트의 구성 요소
- 브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체임
- React DOM이 React 엘리먼트와 일치하도록 DOM을 업데이트 함
- React 엘리먼트는 불변 객체이므로 생성 후 자식이나 속성 변경 불가
- React DOM은 해당 엘리먼트와 그 자식 엘리먼트를 이전의 엘리먼트와 비교해 필요한 경우에만 DOM을 업데이트함
Component and Props
컴포넌트 정의하기
함수 컴포넌트와 클래스 컴포넌트
- 데이터를 가진 하나의 props 객체 인자를 받은 후 React 엘리먼트를 반환하는 React 컴포넌트
function Welcome(props) {
return <h1>Hello, {props.name}</h1>
}
- 같은 기능의 클래스 컴포넌트
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
컴포넌트 렌더링
- React가 사용자정의 컴포넌트로 작성한 엘리먼트를 발견하면 JSX 어트리뷰트와 자식을 해당 컴포넌트에 단일 객체(props)로 전달함
- <Welcome name="Sara" /> 엘리먼트로 ReactDOM.render()를 호출합니다.
- React는 {name: 'Sara'}를 props로 하여 Welcome 컴포넌트를 호출합니다.
- Welcome 컴포넌트는 결과적으로 <h1>Hello, Sara</h1> 엘리먼트를 반환합니다.
- React DOM은 <h1>Hello, Sara</h1> 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트합니다.
- const element = <Welcome name="Sara" />; ReactDOM.render( element, document.getElementById('root') );
- 모든 React 컴포넌트는 자신의 props를 다룰 때 반드시 순수 함수처럼 동작해야 함
State and Lifecycle
state의 생명주기
componentDidMount
- 컴포넌트가 처음 DOM에 렌더링 될 때 실행되는 함수
- ‘마운팅’이라고 불림
componentWillUnmount
- 컴포넌트에 의해 성성된 DOM이 삭제될 때 실행되는 함수
- ‘언마운팅’이라고 불림
setState
- 컴포넌트의 로컬 state를 업데이트해주는 함수
- 인자가 객체일 때 전달된 객체는 현재 state에 병합됨
- 인자가 함수일 때는 전달된 함수의 첫 번째 인자로 이전 state를 받고 두 번째 인자로 업데이트가 적용된 시점의 props를 받음
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
- <Clock />가 ReactDOM.render()로 전달되었을 때 React는 Clock 컴포넌트의 constructor를 호출합니다. Clock이 현재 시각을 표시해야 하기 때문에 현재 시각이 포함된 객체로 this.state를 초기화합니다. 나중에 이 state를 업데이트할 것입니다.
- React는 Clock 컴포넌트의 render() 메서드를 호출합니다. 이를 통해 React는 화면에 표시되어야 할 내용을 알게 됩니다. 그 다음 React는 Clock의 렌더링 출력값을 일치시키기 위해 DOM을 업데이트합니다.
- Clock 출력값이 DOM에 삽입되면, React는 componentDidMount() 생명주기 메서드를 호출합니다. 그 안에서 Clock 컴포넌트는 매초 컴포넌트의 tick() 메서드를 호출하기 위한 타이머를 설정하도록 브라우저에 요청합니다.
- 매초 브라우저가 tick() 메서드를 호출합니다. 그 안에서 Clock 컴포넌트는 setState()에 현재 시각을 포함하는 객체를 호출하면서 UI 업데이트를 진행합니다. setState() 호출 덕분에 React는 state가 변경된 것을 인지하고 화면에 표시될 내용을 알아내기 위해 render() 메서드를 다시 호출합니다. 이 때 render() 메서드 안의 this.state.date가 달라지고 렌더링 출력값은 업데이트된 시각을 포함합니다. React는 이에 따라 DOM을 업데이트합니다.
- Clock 컴포넌트가 DOM으로부터 한 번이라도 삭제된 적이 있다면 React는 타이머를 멈추기 위해 componentWillUnmount() 생명주기 메서드를 호출합니다.
단방향식 데이터 흐름
- 컴포넌트는 자신의 state를 자식 컴포넌트에 props로 전달할 수 있지만 자식 컴포넌트는 props로 전달받은 정보가 어디서부터 온 것인지 알 수 없음
Comments