A JavaScript library for building user interfaces: 화면을 만들기 위한 기능들을 모아놓은 것
장점
A syntax extension to JavaScript: JavaScript + XML/HTML
const element = <h1>Hello, world!</h1>
React에서 JSX를 쓰는 것이 필수가 아님
// JSX를 사용한 경우
class Hello extends React.Component {
render() {
return <div>Hello {this.props.toWhat}</div>;
}
}
ReactDOM.render(
<Hello toWhat="World" />
document.getElementById('root')
);
// JSX를 사용하지 않고 JS를 사용한 경우
class Hello extends React.Component {
render() {
return React.createElement('div', null, `Hello ${this.props.toWhat}`);
}
}
ReactDOM.render(
React.createElement(Hello, {toWhat: 'World'}, null),
document.getElementById('root')
);
JSX는 객체를 나타냄
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
// 위 코드의 결과로 아래와 같은 객체(React elements)가 만들어짐
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
JSX의 장점
Element
// Root DOM node
<div id="root"></div>
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
리액트는 바뀐 부분만 계산을 해서 해당 부분만 새롭게 랜더링함
Components
// PURE - input을 변경하지 않으며, 같은 input에 대해서 항상 같은 output을 리턴
function sum(a, b) {
return a+b;
}
// IMPURE - input을 변경함
function withdraw(account, amount) {
account.total -= amount;
}
Component
function Welcome(props) {
return <h1> Hello, {props.name}</h1>
}
class Welcome extends React.Component {
render() {
return <h1> Hello, {props.name}</h1>
}
}
State
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {
liked: false
};
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
Lifecycle
Copyright@Soaple
<button onClick={activeLasers}>
Activate Lasers
</button>
Event Handler: 이벤트를 처리하는 함수, Event Listener라고도 함
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make 'this' work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
)
}
}
// 또는
class LoggingButton extends React.Component {
// This syntax ensures 'this' is bound within handleCllick.
// Warning: this is *experimental* syntax.
handleClick = () => {
console.log('this is: ', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render (
<Greeting isLoggedIn={false} />, document.getElementById('root')
);
Inline condition
function MailBox(props) {
const unreadMessages = props.unreadMessage;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
If else condition
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
null을 리턴하면 렌더링 되지 않음
function WarningBanner(props) {
if(!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
List
function NumberList(props) {
const numbers = props.numbers;
const listItems = number.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />, documeng.getElementById('root')
);
Keys
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
key로 객체의 ID를 사용하는 경우
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
key로 index를 사용하는 경우 -> index는 고유한 key값은 아님
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
key는 props로 전달되지 않음
const content = posts.map((post) =>
<Post
// 아래에 있는 key는 Post에서 props.key 찍어봐도 안나옴
key={post.id}
// 그래서 id를 전달한다
id={post.id} />
);
Controlled Components는 값이 react의 통제를 받는 Input form element를 의미함
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type='text' value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
File input tag는 값을 읽을 수만 있고 통제할 수 없기 때문에 Uncontrolled Components
Shared State
Composition
function WelcomdDialog() {
return (
<FancyBorder color='blue'>
// 여기서부터
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
// 여기까지 FancyBorder 컴포넌트의 children으로 전달이 됨
</FancyBorder>
);
}
<Dialog
title="Welcome"
message="Thank you for visiting our spacecraft!"
</>
Inheritance
처음 만난 리액트 by goormedu