Hooks 이전
if (컴포넌트 내부 상태가 있을 경우) { class } else if (컴포넌트 내부 상태가 없을 경우) { if (라이프사이클을 사용해야 하는 경우) { class } else if (라이프사이클에 관계 없는 경우) { function } }
Hooks 이후
- class
- function
function 컴포넌트에서도 Hooks을 통해서 상태나 라이프사이클 기능을 이용할 수 있음
import React from 'react'
class ClassComponent extends React.Component {
render() {
return <div>Hello</div>
}
}
// 사용
<ClassComponents />
import React from 'react'
// 정의1
function FunctionComponent1() {
return <div>Hello</div>
}
<FunctionComponent1 /> // 사용
// 정의2
const FunctionComponent2 = () => <div>Hello</div>
<FunctionComponent2 /> // 사용
React.createElement(
type, // 태그 이름 문자열 | 리액트 컴포넌트 | React.Fragment
[props], // 리액트 컴포넌트에 넣어주는 데이터 객체
[...children] // 자식으로 넣어주는 요소들
)
ReactDOM.render(
React.createElement("h1", null, `type이 '태그 이름 문자열'입니다.`)
document.querySelector('#root')
)
const Component = () => {
return React.createElement(
'p',
null,
`type이 '리액트 컴포넌트'입니다.`
)
}
// <Component></Component> => <Component /> => <p>`type이 '리액트 컴포넌트'입니다.`</p>
ReactDOM.render(
React.createElement(Component, null, null),
document.querySelector("#root")
)
Element
를 생성하지 않고 타겟에 주입할 수 있음ReactDOM.render(
React.createElement(
React.Fragment,
null,
`type이 '리액트 컴포넌트'입니다.`
),
document.querySelector("#root")
)
ReactDOM
과 API(React.createElement
)를 호출ReactDOM.render(
React.createElement(
"div",
null,
React.createElement(
"div",
null,
React.createElement('h1', null, '주제'),
React.createElement(
'ul',
null,
React.createElement('li', null, 'React')
React.createElement('li', null, 'Vue')
)
)
)
document.querySelector("#root")
)
JSX 문법으로 작성된 코드는 순수한 JS로 컴파일하여 사용한다
Q. 이 컴파일을 누가 해준다? A. babel
ex) 바벨에서의 컴파일 예시
<div>hello</div>
⇒ React.createElement('div', null, 'hello')
$ install babel
// <script type="text/javascript"> // 기존
<script type="text/babel"> // 수정
ReactDOM.render(
<div>
<div>
<h1>주제</h1>
<ul>
<li>React</li>
<li>Vue</li>
</ul>
</div>
</div>,
document.querySelector("#root")
)
Q. 왜 JSX를 쓰나요?
A1. React.createElement보다 JSX의 가독성이 훨씬 좋음
A2. babel과 같은 컴파일 과정에서 문법적 오류를 인지하기 쉬움
<>자식들</>
을 사용합니다. => Fragment
{표현식}
을 이용함<p>어쩌구</p>
<br />
Props
는 컴포넌트 외부에서 컴포넌트에게 주는 데이터State
는 컴포넌트 내부에서 변경할 수 있는 데이터function Component(props) {
return {
<div>
<h1>{props.message}, 함수로 만든 컴포넌트</h1>
<div>
}
}
ReactDOM.render(
<Component message="안녕하세요~" />,
document.querySelector("#root")
)
function Component(props) {
return {
<div>
<h1>{props.message}, 함수로 만든 컴포넌트</h1>
<div>
}
}
Component.defaultProps = {
message: '기본값!!'
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<div>
}
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<div>
}
}
Component.defaultProps = {
message: '기본값'
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<div>
}
static defaultProps = {
message: "기본값2"
}
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<p>{this.state.count}</p>
<div>
}
componentDidMount() { // lifecycle hook
setTimeout(() => {
// this.state.count += 1
this.setState({
count: this.state.count + 1
})
}, 1000)
}
static defaultProps = {
message: "기본값2"
}
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
state = {
count: 0
}
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<p>{this.state.count}</p>
<div>
}
componentDidMount() { // lifecycle hook
setTimeout(() => {
// this.state.count += 1
this.setState({
count: this.state.count + 1
})
}, 1000)
}
static defaultProps = {
message: "기본값2"
}
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
class Component extends React.Component {
state = {
count: 0
}
render() {
<div>
<h1>{this.props.message}, 클래스로 만든 컴포넌트</h1>
<p>{this.state.count}</p>
<div>
}
componentDidMount() { // lifecycle hook
setTimeout(() => {
// this.state.count += 1
// this.setState({
// count: this.state.count + 1
// })
this.setState((previousState) => {
const newState = {count: previousState.count + 1}
return newState
})
}, 1000)
}
static defaultProps = {
message: "기본값2"
}
}
ReactDOM.render(
<Component message="hello~" />,
document.querySelector("#root")
)
on
이 붙음onClick
, onMouseEnter
이벤트 = {함수}
props
로 전달함function Component() {
return {
<div>
<button
onClick={() => {
console.log("clicked")
}}
>
클릭
</button>
<div>
}
}
ReactDOM.render(
<Component />,
document.querySelector("#root")
)
class Component extends React.Component {
render() {
return {
<div>
<button
onClick={() => {
console.log("clicked")
}}
>
클릭
</button>
<div>
}
}
}
ReactDOM.render(
<Component />,
document.querySelector("#root")
)
class Component extends React.Component {
state = {
count: 0
}
render() {
return {
<div>
<p>{this.state.count}</p>
<button
onClick={() => {
console.log("clicked")
this.setState((state) => ({
...state,
count: state.count + 1
}))
}}
>
클릭
</button>
<div>
}
}
}
ReactDOM.render(
<Component />,
document.querySelector("#root")
)
class Component extends React.Component {
state = {
count: 0
}
// constructor(props) {
// super(props)
// this.click = this.click.bind(this)
// }
render() {
return {
<div>
<p>{this.state.count}</p>
<button
onClick={() => {
}}
>
클릭
</button>
<div>
}
}
}
click = () => {
console.log("clicked")
this.setState((state) => ({
...state,
count: state.count + 1
}))
}
ReactDOM.render(
<Component />,
document.querySelector("#root")
)
class App extends React.Component {
state = {
age: 39,
}
constructor(props) {
super(props)
console.log("constructor", props)
}
render() {
console.log('render')
return (
<div>
<h2>
Hello {this.props.name} - {this.state.age}
</h2>
</div>
)
}
componentWillMount() {
console.log("componentWillMount")
}
componentDidMount() {
console.log("componentDidMount")
setInterval(() => {
this.setState(state => ({ ...state, age: state.age + 1 }))
})
}
}
ReactDOM.render(<App name="Mark" />, document.querySelector("#root"))