단점 : 검색 엔진 노출에 어려움이 있다.
class LikeButton extends React.Component {
}
=> 클래스형
const LikeButton = () => {};
function LikeButton() {}
=> 함수형
like-button.html
<html>
<head>
<meta charset="utf-8">
<title>웹게임</title>
</head>
<body>
<div id="root"></div>
<!-- 남의 코드 불러올 때 사용 -->
<!-- 개발용 -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<!-- 배포용 -->
<!--<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>-->
<!--<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>-->
<script>
'use strict';
const e = React.createElement;
// 원시적인 형태
// 리액트 = js
// 리액트는 데이터 중심으로 움직인다.
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'); // 화면
} // => 데이터가 바뀌면 화면이 바뀐다. : 화면에서 바뀔 부분을 state로 만든다.
} // class는 거의 사용하지 않음 : ErrorBoundary에서 사용 (1%)
// => 컴포넌트 : 데이터와 화면을 하나로 묶어둔 덩어리
//const LikeButton = () => {};
//function LikeButton() {}
</script>
<script>
ReactDOM.createRoot(document.querySelector('#root')).render(e(LikeButton));
// LikeButton 이라는 컴포넌트를 <div id="root"></div> 여기 안에다가 컴포넌트를 그린다.
</script>
</body>
</html>
like-button-jsx.html
<html>
<head>
</head>
<body>
<div id="root"></div>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> <!-- babel을 사용하기 위한 script -->
<!--<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>-->
<!--<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>-->
<script type="text/babel">
'use strict';
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {liked: false};
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return (
<button onClick={() => this.setState({liked: true})}>
Like
</button>
); // 실무에서 주로 쓰임
} // => babel을 추가하지 않으면 작동하지 않음
}
</script>
<script type="text/babel">
// ReactDOM.render(<LikeButton />, document.querySelector('#root')); // React 17버전 코드
ReactDOM.createRoot(document.querySelector('#root')).render(<LikeButton/>); // React 18버전 코드
</script>
</body>
</html>
return (
<button onClick={() => this.setState({liked: true})}>
Like
</button>
);
이 것을
return e('button', {onClick: () => this.setState({liked: true})}, 'Like');
이 것으로 바꾸어준다.
예시
const array = []; // 배열도 객체
pop, push, shift, unshift, splice -> 배열을 직접적으로 수정 // React에서는 사용하지 않음
concat, slice -> 새로운 배열을 만들어냄
return (
<button onClick={() => {
this.setState({liked: true});
}}>
Like
</button>
);
// 함수 컴포넌트는 this를 쓸 일이 없다.
// const LikedButton = () => {} // 화살표 함수
function LikeButton() { // 함수형 컴포넌트 X 함수 컴포넌트 O
const [liked, setLiked] = React.useState(false); // 구조분해
// liked : 데이터, setLiked : 데이터를 바꾸는 함수
// -> 뭔 짓을 하든, 결국 return한게 화면이다.
/*
js 옛날 문법
const result = React.useState(false);
const liked = result[0];
const setLiked = result[1];
*/
/*
// 예시
const[news, setNews] = React.useState(['뉴스1', '뉴스2', '뉴스3', '뉴스4', '뉴스5'])
const [category, setCategory] = React.useState(['스포츠', '연예', '경제', '시사', '정치'])
if(category === '뉴스') {
return '뉴스화면'
} // 데이터들을 사용해서 화면 리턴
*/
if(liked) {
return 'You liked this.';
}
return (
<button onClick={() => {setLiked(true);}}>Like</button>
);
}
index.html
<html>
<head>
<meta charset="UTF-8" />
<title>구구단</title>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
class GuGuDan extends React.Component {
constructor(props) {
super(props);
this.state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
}
render() {
return (
<div>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
{/* 중간에 js를 삽입하고 싶으면 {}를 사용한다. */}
<form>
<input type="number" value={this.state.value} onChange={(e) => this.setState({value: e.target.value})} />
{/* input.onChange = (e) => {console.log(e.target.value)} : 글자 치는 것이 콘솔에 나오게 함 ↑ */}
<button>입력!</button>
</form>
<div>{this.state.result}</div>
</div>
);
}
}
</script>
<script type="text/babel">
ReactDOM.createRoot(document.querySelector('#root')).render(<GuGuDan/>);
</script>
</body>
</html>
index.html
구구단 컴포넌트
<html>
<head>
<meta charset="UTF-8" />
<title>구구단</title>
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
class GuGuDan extends React.Component {
constructor(props) {
super(props);
this.state = { // 변할 것들
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
}
onSubmit = (e) => { // submit할 때 실행
e.preventDefault();
if(parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: '정답',
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
});
} else {
this.setState({
result: '땡',
value: '',
});
}
}
onChange = (e) => {
this.setState({value: e.target.value})
};
render() {
return (
<div>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
{/* 중간에 js를 삽입하고 싶으면 {}를 사용한다. */}
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
{/* input.onChange = (e) => {console.log(e.target.value)} : 글자 치는 것이 콘솔에 나오게 함 ↑ */}
<button>입력!</button>
{/* 기본 이벤트 핸들러 : onClick, onChange, onSubmit, onLoad, onInput, onFocus, onBlur */}
</form>
<div>{this.state.result}</div>
</div>
);
}
}
</script>
<script type="text/babel">
ReactDOM.createRoot(document.querySelector('#root')).render(<div><GuGuDan/><GuGuDan/></div>);
</script>
</body>
</html>
<div>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
{/* 중간에 js를 삽입하고 싶으면 {}를 사용한다. */}
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
{/* input.onChange = (e) => {console.log(e.target.value)} : 글자 치는 것이 콘솔에 나오게 함 ↑ */}
<button>입력!</button>
{/* 기본 이벤트 핸들러 : onClick, onChange, onSubmit, onLoad, onInput, onFocus, onBlur */}
</form>
<div>{this.state.result}</div>
</div>
<>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
<button>입력!</button>
</form>
<div>{this.state.result}</div>
</>
<>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
<button>입력!</button>
</form>
<div>{this.state.result}</div>
</>
form 태그가 있을 때는 onSubmit 사용
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
<button type="submit">입력!</button>
</form>
--------------------------------------------------------
form이 없으면 onClick 사용
<input type="number" value={this.state.value} onChange={this.onChange} />
<button onClick={this.onSubmit}>입력!</button>
onSubmit = (e) => { // submit할 때 실행
e.preventDefault();
if(parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: '정답',
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
});
} else {
this.setState({
result: '땡',
value: '',
});
}
};
onChange = (e) => {
this.setState({value: e.target.value})
};
// constructor 포함
class GuGuDan extends React.Component {
constructor(props) {
super(props);
this.state = { // 변할 것들
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
}
}
----------------------------------------
// constructor 미포함
class GuGuDan extends React.Component {
state = { // 변할 것들
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
}
onSubmit = (e) => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: '정답: ' + this.state.value, // 정답 값 표시하기 (현재 값)
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
});
this.input.focus();
} else {
this.setState({
result: '땡',
value: '',
});
this.input.focus();
}
};
onSubmit = (e) => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState((prevState) => {
return {
result: '정답: ' + prevState.value, // 정답 값 표시하기 (현재 값) => 현재 state
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
// => 미래 state
};
});
this.input.focus();
} else {
this.setState({
result: '땡',
value: '',
});
this.input.focus();
}
};
<html>
<head>
<meta charset="UTF-8"/>
<title>구구단</title>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root"></div> <!-- 결과: <div id="root"><button>Like</button></div> -->
<script type="text/babel">
class GuGuDan extends React.Component {
state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
onSubmit = (e) => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState((prevState) => {
return {
result: '정답: ' + prevState.value, // 정답 값 표시하기 (현재 값) => 현재 state
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
// => 미래 state
};
});
this.input.focus();
} else {
this.setState({
result: '땡',
value: '',
});
this.input.focus();
}
};
onChange = (e) => {
this.setState({ value: e.target.value });
};
input;
onRefInput = (c) => { this.input = c; };
// 컨텐츠
render() {
console.log('렌더링'); // setState를 할 때마다 render 함수가 실행된다.
return (
<React.Fragment>
<div>{this.state.first} 곱하기 {this.state.second}는?</div>
<form onSubmit={this.onSubmit}>
<input ref={this.onRefInput} type="number" value={this.state.value} onChange={this.onChange}/>
<button>입력!</button>
</form>
<div>{this.state.result}</div>
</React.Fragment>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<GuGuDan/>, document.querySelector('#root'));
</script>
</body>
</html>
Inflearn - 웹 게임을 만들며 배우는 React (조현영 (제로초))