<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<html>
<head>
<!-- 주의: 사이트를 배포할 때는 "development.js"를 "production.min.js"로 대체하세요. -->
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
</head>
<body>
<div id="root"></div>
<script>
// react.js
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props){
super(props);
}
render() {
return e('button', null, 'Like'); // <button>Like</button> 생성하겠다는 계획
}
}
</script>
<script>
// react-dom.js
ReactDOM.render(e(LikeButton), document.querySelector('#root')); // root div에 Like 버튼 DOM 생성
</script>
</body>
</html>
return e('button', {onClick: () => {console.log('clicked')}, type: 'submit'}, 'Like');
class LikeButton extends React.Component {
constructor(props){
super(props);
this.state = { // 상태값 설정
liked: false,
}
}
render() {
return e(
'button',
{onClick: () => {this.setState({liked: true})}, type: 'submit'},
this.state.liked === true ? 'Liked' : 'Liked',
); // 버튼 클릭하면 liked state를 true로 변경 / liked가 true면 버튼 텍스트를 Liked로 변경
}
}
}
❗ 크롬 react 확장 프로그램을 설치하고 Components에서 컴포넌트 단위로 state 등 확인 가능
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">...</script>
<div id="root"></div>
<script type="text/babel">
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props){
super(props);
this.state = {
liked: false,
}
}
render() {
return <button type="submit" onClick={() => {this.setState({liked: true})}}>
{this.state.liked === true ? 'Liked' : 'Like'}
</button>;
}
}
</script>
<script type="text/babel">
ReactDOM.render(<LikeButton />, document.querySelector('#root')); // root div에 Like 버튼 DOM 생성
</script>
👉 똑같은 버튼을 여러 개 만들고 싶으면 만 추가하면 되고, 수정은 한 번만 하면 되므로 재사용이 쉽다.
<input />
{}
) 안에서 state값 사용 <div id="root"></div>
<script type="text/babel">
class GuGuDan extends React.Component {
constructor(props) {
super(props);
this.state = { // 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>
<form>
<input type="number" value={this.state.value} />
<button>입력!</button>
</form>
<div>{this.state.result}</div>
</div>
);
}
}
</script>
<script type="text/babel">
ReactDOM.render(<GuGuDan />, document.querySelector('#root'));
</script>
<input ... onChange={(e) => this.setState({value: e.target.value})} />
function(){}
을 사용할 수 없고 화살표 함수를 사용해야 함!class GuGuDan extends React.Component {
constructor(props) {
...
}
onSubmit = (e) => {
e.preventDefault();
if(parseInt(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>
<form onSubmit={this.onSubmit}> <!-- 클래스 메서드 사용 -->
<input type="number" value={this.state.value} onChange={this.onChange} /> <!-- 클래스 메서드 사용 -->
<button type="submit">입력!</button>
</form>
<div>{this.state.result}</div>
</div>
);
}
}
ReactDOM.render(<div><GuGuDan /><GuGuDan /><GuGuDan /></div>, document.querySelector('#root'));
<div>
태그로 감싸야 하는 규칙이 있음<React.Fragment>
로 대체하여 제거할 수 있음render() {
return (
<React.Fragment>
<div>{this.state.first} 곱하기 {this.state.second}은(는)?</div>
<form onSubmit={this.onSubmit}>
<input type="number" value={this.state.value} onChange={this.onChange} />
<button type="submit">입력!</button>
</form>
<div>{this.state.result}</div>
</React.Fragment>
);
}
constructor
를 사용하지 않는 경우가 많음state
를 선언하여 사용state = {
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
result: '',
};
if(parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState((prevState) => { // 함수형 setState에서 이전 state를 활용 가능
return {
result: '정답 ' + prevState.value,
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
value: '',
}
});
}
❗ react는 비동기 방식이므로 이전 state를 활용하려면 안전하게 함수형 setState를 사용하도록 한다.
onSubmit = (e) => {
e.preventDefault();
if(parseInt(this.state.value) === this.state.first * this.state.second) {
...
this.input.focus(); // input에 포커스
}else{... }
};
input; // input 선언
render() {
return (
<input ref={(c) => {this.input = c;}} ... /> // input이 이 태그를 참조하도록 함
);
}
❗
setState
가 실행될 때마다render()
가 실행된다. 페이지가 무거워지면 과부하가 생길 수 있으므로 유의하도록 한다.
render()
가 실행될 때마다 함수를 생성하는 일이 없도록 메서드를 따로 선언하는 것이 좋음onRefInput = (c) => {this.input = c;};
render() {
console.log('렌더링');
return (
...
<input ref={this.onRefInput} ... />
...
);
}