리액트에서는 jsx파일로 코드를 작성하는데 jsx란 쉽게 말해
자바스크립트안에서 html마크업을 사용할수 있는 자바스크립트의 확장버전이다.
아래와 같은 특징들이 있다.
// in html
<h1 class="title" onclick="">hello!</h1>
// in jsx
<h1 className="title" onClick="">hello!</h1>
class
는 className
으로, onclick
은 onClick
으로 작성해야한다.
// 리턴 값으로 2개 이상의 요소를 반환할 수 없다
function App() {
return (
<h1></h1>
<h1></h1>
);
}
// 아래와 같인 묶어서 하나의 요소로 반환해야 한다.
function App() {
return (
<div>
<h1></h1>
<h1></h1>
</div>
);
}
// 또는
function App() {
return (
<React.Fragment>
<h1></h1>
<h1></h1>
</React.Fragment>
);
}
// 또는
function App() {
return (
<>
<h1></h1>
<h1></h1>
</>
);
}
function App() {
const name = younoah;
return (
<>
<h1>hello</h1>
{name && <h1>{name}</h1>}
</>
);
}
결국 유저에게 보여지는 것은 index.html이다.
우리가 만든 리액트 컴포넌트들을 바벨로 순수 자바스크립트로 바꾸고 HTML과 연결하는 작업이 필요하다.
react-dom은 리액트로 작성한 컴포넌트를 HTML과 연결하는 역할을 한다.
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<div id="root"></div>
</body>
</html>
import React from 'react';
function App() {
return <h1>Hello :)</h1>;
}
export default App;
import ReactDOM from 'react-dom';
import App from './app';
ReactDOM.render(
<React.StrictMode> //리엑트의 엄격모드, 생략가능
<App />
</React.StrictMode>,
document.getElementById('root')
);
우리가 만든 App이라는 최상위 컴포넌트를 index.html에 있는 root라는 아이디를 가지 요소에 연결하여 렌더링한다.
리액트에서의 event는 일반 DOM요소에서 발생하는 이벤트 객체와는 약간 다르다.
리액트는 리액트 나름대로 이벤트를 한 단계 더 감싸는 자신만의 이벤트 클래스를 사용한다. 그것이 SyntheticEvents 이다.
일반적인 DOM요소에서 발생하는 이벤트를 사용하는것처럼 사용할 수 있다.
Ref는 render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법이다.
일반적으로 자바스크립트에서 다른 DOM요소의 값을 참고할 때
const value = document.querySelector()
를 사용한다.
리액트에서는 DOM요소를 직접적으로 사용하지 않기 때문에 다른 리액트의 요소에 접근하고 싶다면 Ref를 사용하면된다.
class HabitAddForm extends Component {
formRef = React.createRef();
inputRef = React.createRef();
onSubmit = event => {
event.preventDefault();
const name = this.inputRef.current.value;
name && this.props.onClickAdd(name);
// this.inputRef.current.value = '';
this.formRef.current.reset();
};
render() {
return (
<form ref={this.formRef} className="add-form" onSubmit={this.onSubmit}>
<input
ref={this.inputRef}
type="text"
className="add-input"
placeholder="Habit"
/>
<button className="add-button">Add</button>
</form>
);
}
}
컴포넌트 안에서 정의한 state 객체이다.
컴포넌트의 데이터를 보관하기 위한 객체로, state 객체를 통해서 데이터 업데이트가 발생하면 render함수가 호출된다.
리액트에서 state객체는 불변객체로 사용함으로써 얘기치 못한 에러를 방지하자.
컴포넌트 밖에서 주어지는 데이터이다.
재사용을 높이기 위해 데이터를 외부에서 받아 데이터에 맞게 UI를 보여주기 위해 사용된다.
아래와 같이 부모 컴포넌트에서 LikeButton
컴포넌트를 사용할 때 title, onClick 과 같은 인자로 전달해주면 LikeButton
컴포넌트의 props라는 객체로 묶여서 전달된다.
<LikeButton title={'Like'} onClick={this.handleClick} />
리액트의 Component에서 제공하는 setState함수를 사용하여 상태를 변경해주어야 비로소 상태가 변경된 것을 인식하고 렌더링을 한다.
import React, { Component } from 'react';
class Habbit extends Component {
state = {
count: 0,
};
handleIncreament = () => {
// state 오브젝트 안에 있는 count를 증가 한 뒤 state를 업데이트 해야 함
// 아래와 같은 방식으로 사용하면 리액트는 상태가 업데이트 되었는지 모른다.
// this.state.count += 1;
// 리액트의 Component에서 제공하는 setState함수를 사용하여 상태를 변경해주어야
// 비로소 상태가 변경된 것을 인식하고 렌더링을 한다.
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<>
<li className="habit">
...
<button
className="habit-button habit-increase"
onClick={this.handleIncreament}
>
...
</li>
</>
);
}
}
export default Habbit;
setState()의 인자에 객체로 넘겨주는 것에 눈여겨 보자. 객체를 새로 세팅하는 방식인듯 하다.