whatisthis?
220313 [TIL] Today I Learned 💯 React.js 본문
React.js
선언형
코드를 예측 가능하고 디버그하기 쉽게 만들어줌.
컴포넌트 기반
다양한 형식의 데이터를 앱 안에서 손쉽게 전달할 수 있고, DOM과는 별개로 상태를 관리할 수 있음.
💡 웹팩(webpack)의 기능
- 쪼개진 js 파일을 html이 실행할수 있는 하나의 파일로 합쳐준다.
React 클래스 컴포넌트
HTML
<head>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
</head>
<body>
<div id="root"></div>
<script src="./like-button.js"></script>
<script src="./ReactDOM.js"></script>
</body>
like-button.js
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
}
render() {
return e("button", null, "like");
}
}
클래스형 컴포넌트
- class 클래스명 extends React.Component {
constructor(props) {
super(props);
}
>> 부모 클래스인 React.Component의 props 객체를 가져오는것임.
ReactDOM.js
ReactDOM.render(e(LikeButton), document.querySelector("#root"));
1/ element를 생성
React.createElement 메소드 사용
2/ reactDOM으로 렌더링함
ReactDOM.render(변수명, root);
📃 클래스 사용시
- 빈 element 만들고
- 클래스 선언하고
- 클래스 내 render()부분에
> render() { return 변수명(태그명, props, 내용) }
- ReactDOM.render(변수명, root)
props는 객체 형식으로 ,로 구분해서 작성하면 됨.
예>
{onClick: () => {console.log('clicked')}, type = 'submit'}
** 속성명은 js문법대로 camelCase로 써준다.
html에선 onclick이지만, js에선 onClick
state
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {
liked: false,
};
}
render() {
return e(
"button",
{
onClick: () => {
this.setState({ liked: true });
},
type: "submit",
},
"like"
);
}
}
클래스형 컴포넌트이므로
contructor() { } 블록 안에 state를 선언해준다.
클래스이므로 this가 붙어야한다.
반드시 어디서 값을 불러올때
this.state.liked << 이렇게 불러와야함.
단, setState함수 내에서는
this.setState( {liked: true} ) 이렇게 liked라고만 해줘도 된다.
+)
chrome 확장프로그램 react dev-tool 설치완료 :)
- 컴포넌트 단위로 확인 가능하다.
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {
liked: false,
};
}
render() {
return e(
"button",
{
onClick: () => {
if (this.state.liked === false) {
this.setState({ liked: true });
} else {
this.setState({ liked: false });
}
},
type: "submit",
},
this.state.liked === true ? "liked" : "like"
);
}
}
JSX
위 방법은 너무 복잡하고 보기 안좋으므로
JSX라는 문법으로 작성해보자.
return e(
"button",
{
onClick: () => {this.setState({ liked: true });
},
type: "submit",
},
this.state.liked === true ? "liked" : "like"
);
🔺 이렇게 보기 안좋았던 코드가
🔻 이렇게 html 태그형식으로 보기좋게! (JSX)
return (
<button
onClick={() => {
this.setState({ liked: true });
}}
>
{liked}
</button>
);
ReactDOM 부분도 이런식으로 작성해준다.
ReactDOM.render(<LikeButton />, document.querySelector("#root"));
단, JSX 문법을 웹브라우저가 해독을 못하기 때문에
자바스크립트 컴파일러인 Babel을 이용해줘야함!
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
그리고, 컴포넌트를 담은 js파일에 type="text/babel"이라고 추가해준다.
<script src="./like-button.js" type="text/babel"></script>
JSX = JavaScript + XML로,
반드시 닫는태그 />를 해줘야함. 문법이 엄격.
JSX안에서 javascript를 쓰려면 { } 안에 넣어줘야함.
+ 참고
{} | curly brackets |
[] | square brackets |
() | parentheses |
Babel은 JSX 문법을 브라우저가 이해할 수 있게 (위에서 했던대로 createElement ~~) 바꿔준다.
💯 예제 - 구구단 게임 제작
- 클래스 컴포넌트 이용
- 한번 submit 할때마다 랜덤으로 문제의 숫자가 바뀜
- 정답이면 ? - 정답입니다 / 오답이면 ? - 틀렸습니다 를 표시하는 공간이 하단에 존재함.
- input의 value, result부분, 그리고 두 숫자를 state로 지정해 변하도록 조정 - setState
- 그 외 조건은 상동. (babel, react, reactdom 임포트하고, ReactDOM.render 부분)
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: "",
};
this.onFormSubmit = e => {
e.preventDefault();
console.log(e);
if (this.state.value == this.state.first * this.state.second) {
this.setState({ result: "⭕정답입니다" });
} else {
this.setState({ result: "❌틀렸습니다" });
}
this.setState({ value: "" });
this.setState({
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
});
};
}
render() {
return (
<div>
<h1>💯구구단 게임💯</h1>
<div>
📃 {this.state.first} 곱하기 {this.state.second} 는?
</div>
<form onSubmit={this.onFormSubmit}>
<input
type="number"
required
placeholder="정답 입력"
value={this.state.value}
onChange={e => {
this.setState({ value: e.target.value });
}}
/>
<button type="submit">입력</button>
</form>
<div>{this.state.result}</div>
</div>
);
}
}
+) 참고 - 메모
input의 onChange함수는 코드가 짧아서 arrow function으로 바로 JSX 코드내 { }안에 적었고,
form의 onSubmit함수는 코드가 길어서 따로 GuGuDan클래스의 메소드로 선언해주었다.
(this.onFormSubmit 함수)
++) 조금 수정한 것
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: "",
};
}
onFormSubmit = e => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: "⭕정답입니다",
value: "",
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
});
} else {
this.setState({ result: "❌틀렸습니다", value: "" });
}
};
onInputChange = e => {
this.setState({ value: e.target.value });
};
render() {
return (
<div>
<h1>💯구구단 게임💯</h1>
<div>
📃 {this.state.first} 곱하기 {this.state.second} 는?
</div>
<form onSubmit={this.onFormSubmit}>
<input
type="number"
required
placeholder="정답 입력"
value={this.state.value}
onChange={this.onInputChange}
/>
<button type="submit">입력</button>
</form>
<div>{this.state.result}</div>
</div>
);
}
}
변경사항
1. 나는 constructor() {} 블록 안에 this.onFormSubmit을 선언했었는데,
이렇게 하지말고 그냥 클래스 메소드로 선언하자.
constructor 안에 있는 함수 = 클래스로 객체가 생성되었을때 실행되는 코드들임
그 아래에, 즉 render() 윗줄에다가
onFormSubmit으로 선언하고, (선언시 this. 필요없다.)
JSX안에서 사용할땐 (호출시) {this.onFormSubmit} 으로 this.를 붙여줘야함!
2. 왠만해선 JSX안에서 함수 직접 쓰지말고,
따로 뺴서 관리하자.!! 싶어서
onInputChange도 위로 빼서 따로 선언했다.
3. 정답일 때와 오답일 때 둘다 숫자가 재설정되도록 했었는데,
정답일때만 바뀌는게 맞는것 같아서 수정했다.
onFormSubmit = e => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({ result: "⭕정답입니다" });
} else {
this.setState({ result: "❌틀렸습니다" });
}
this.setState({
value: "",
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
});
};
🔺수정 전
🔻수정 후
onFormSubmit = e => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: "⭕정답입니다",
value: "",
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
});
} else {
this.setState({ result: "❌틀렸습니다", value: "" });
}
};
+++) 기능 추가 - 지난 정답 로그 보기
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: "",
line: "",
};
}
onFormSubmit = e => {
e.preventDefault();
if (parseInt(this.state.value) === this.state.first * this.state.second) {
this.setState({
result: "⭕정답입니다",
value: "",
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
line:
this.state.first +
"*" +
this.state.second +
"=" +
this.state.first * this.state.second,
});
} else {
this.setState({ result: "❌틀렸습니다", value: "" });
}
};
onInputChange = e => {
this.setState({ value: e.target.value });
};
render() {
return (
<div>
<h1>💯구구단 게임💯</h1>
<div>
📃 {this.state.first} 곱하기 {this.state.second} 는?
</div>
<form onSubmit={this.onFormSubmit}>
<input
type="number"
required
placeholder="정답 입력"
value={this.state.value}
onChange={this.onInputChange}
/>
<button type="submit">입력</button>
</form>
<span>LOG 🔎 {this.state.line}</span>
<div>{this.state.result}</div>
</div>
);
}
}
🔻 이부분을 잘 보자
// 정답이면
this.setState({
result: "⭕정답입니다",
value: "",
first: Math.ceil(Math.random() * 9),
second: Math.ceil(Math.random() * 9),
line:
this.state.first +
"*" +
this.state.second +
"=" +
this.state.first * this.state.second,
});
'WEB STUDY > REACT' 카테고리의 다른 글
220315 [TIL] Today I Learned 💯 React.js - (1) (0) | 2022.03.15 |
---|---|
220314 [TIL] Today I Learned 💯 React.js (0) | 2022.03.14 |
React. React JS - Cleanup function (0) | 2022.02.18 |
React. React JS - Effects (2) Deps (0) | 2022.02.18 |
React. React JS - Effects (1) (0) | 2022.02.18 |