어제 한 거 복습 및 오류 수정
어제 코드 setInterval(callback, 1000)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Practice</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class Clock extends React.Component{
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
}
render(){
console.log('render합니다.') // console.log 찍어보기
setInterval(()=>{
this.setState({time:new Date().toLocaleTimeString()})
},1000)
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
</body>
</html>
render 하는 수를 console.log 찍어보면 재귀로 돌려져서 제곱씩 console.log 가 늘어남 -> 수정 필요 ! ↓↓
componentDidMount(){} 함수 사용 -> 따로 빼주기 ! or ComponentDidMout()함수를 안쓴 채로 바로 constructor 함수 안에 넣어줘도 된다. (포스팅 끝에 가능한 4가지 코드 첨부)
<script type="text/babel">
class Clock extends React.Component{
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
}
componentDidMount(){
setInterval(()=>{
this.setState({time:new Date().toLocaleTimeString()})
},1000)
}
render(){
console.log('render합니다.')
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
설치해두면 좋은 React Developer Tools -> react 로 만든 elements 를 확인할 수 있다
STATE 끌어 올리기 Ⅰ
1. 기본 + class App component 세팅 (state.name='emily', return state.name)
class App extends React.Component{
constructor(props){
super(props)
this.state={
name:'emily'
}
}
render(){
return(
<div>
{this.state.name}
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
* return 할 때 괄호는 안써도 무방 ! 코드에서 (연산 제외) 괄호들은 보통 들여쓰기 / 보기 편함을 위해 쓴다고 한다!
* return 할 때 최상위 노드만 return 이 되어서 밑에 다른 elemnet를 쓰면 오류가 난다. 그래서 react배울 때 꼭 return하고 <> </> or <div> </div> 이렇게 하는걸 습관을 들였다고 함 !
2. Name component 만들기 (App에서 Name Component에 value라는 변수로 본인(App의 .state의) name 이라는 값을 보내줌 + Name return (App에서 받은 값 this.props.value)
* value 라고 칭한 변수는 마음대로 변경 가능 ! (말 그대로 변수)
<body>
<div id="root"></div>
<script type="text/babel">
class Name extends React.Component{
render(){
return(
<>
{this.props.value}
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
name:'emily'
}
}
render(){
return(
<div>
{this.state.name} <Name value={this.state.name} />
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
</html>
1초씩 1을 더해서 출력해보기
<body>
<div id="root"></div>
<script type="text/babel">
class Name extends React.Component {
render() {
return (
<>
{this.props.value}
</>
)
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
name: 'emily'
}
setInterval(()=>{
this.setState({name: this.state.name +='1'})
},1000)
}
render() {
console.log('rendering')// 1초마다 1이 더해져서 출력 됨
return (
<div>
{this.state.name} <Name value={this.state.name} />
</div>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
STATE 끌어 올리기 Ⅱ
목표 : 아래 그림처럼 class App -> C -> B -> A 까지 연동(?) 시키기
1. 기본React 세팅 + App Component (속성 : state=text : ' Good afternoon!' ) + C,B,A class기본으로 만들기
<body>
<div id="root"></div>
<script type="text/babel">
class A extends React.Component{
render(){
return ;
}
}
class B extends React.Component{
render(){
return ;
}
}
class C extends React.Component{
render(){
return ;
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
text:'Good afternoo운'
}
}
render(){
return(
<>
{this.state.text}
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
2. 차례로 불러오기
<body>
<div id="root"></div>
<script type="text/babel">
class A extends React.Component{
render(){
return(
<>
내가 A 이쥬
</>
)
}
}
class B extends React.Component{
render(){
return(
<>
<A />
</>
)
}
}
class C extends React.Component{
render(){
return (
<>
<B/>
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
text:'Good afternoo운'
}
}
render(){
return(
<>
<C/>
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
3. 이제 App state.text 를 A 로 끌어 올리기
<body>
<div id="root"></div>
<script type="text/babel">
class A extends React.Component{
render(){
return(
<>
{this.props.valueFromBandC}
</>
)
}
}
class B extends React.Component{
render(){
return(
<>
<A valueFromBandC={this.props.valueFromC}/>
</>
)
}
}
class C extends React.Component{
render(){
return (
<>
<B valueFromC={this.props.value}/>
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
text:'Good afternoo운'
}
}
render(){
return(
<>
<C value={this.state.text}/>
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
if 조건부 랜더링
4. 위의 코드 그대로 사용해서, App state=isLogin : flase 넣기 / return 삼항 연산자 추가
class App extends React.Component{
constructor(props){
super(props)
this.state={
text:'Good afternoo운',
isLogin: false,
}
}
render(){
return(
<>
{this.state.isLogin ? <C value={this.state.text}/> : '로그인하세요'}
</>
)
}
}
isLogin 이 true 면 this.state.text를 C로 보내고 false경우에는 '로그인하세요' return
5. '로그인하세요' 를 버튼으로 만들고 onClick (isLogin -> True 되는) event 추가
click=()=>{
this.setState({isLogin:true})
}
render(){
return(
<>
{this.state.isLogin ? <C value={this.state.text}/> : <button onClick={this.click}>'로그인하세요'</button>}
</>
)
}
6. 로그아웃 눌렀을 때 다시 돌아오게 만들기 (A 로 함수 보내기 )
<body>
<div id="root"></div>
<script type="text/babel">
class A extends React.Component{
render(){
return(
<>
{this.props.valueFromBandC}
<button onClick={this.props.logout} >로그아웃</button>
</>
)
}
}
class B extends React.Component{
render(){
return(
<>
<A valueFromBandC={this.props.valueFromC} logout={this.props.logout}/>
</>
)
}
}
class C extends React.Component{
render(){
return (
<>
<B valueFromC={this.props.value} logout={this.props.logout}/>
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
text:'Good afternoo운',
isLogin: false,
}
}
click=()=>{
this.setState({isLogin:true})
}
logout=()=>{
this.setState({isLogin:false})
}
render(){
return(
<>
{this.state.isLogin ? <C value={this.state.text} logout={this.logout}/> : <button onClick={this.click}>로그인하기</button> }
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
Event & Form 끌어 올리기 Ⅲ
1. App component 기본 세팅 return input, button +, button -
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props)
this.state={
count:0
}
}
render(){
return(
<>
<input type="number" name="inputbox" value={this.state.count} />
<button>+</button>
<button>-</button>
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
onChange 함수 넣기
* parseInt() 매서드로 input box에 입력된 값 STRING -> int로 만들어주기 !!!
onChange=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.value)
this.setState({count:parseInt(e.target.value)})
}
render(){
return(
<>
<input type="number" name="inputbox" value={this.state.count} onChange={this.onChange} />
<button onClick={this.up}>+</button>
<button onClick={this.down}>-</button>
</>
)
}
console.log(e) -> ? ? ? SyntheticBaseEvent
console.log(e.target) -> 함수 실행시킨 input box
console.log(e.target.value) -> input box 에 넣은 값
button을 누르면 up, down 되는 함수 만들기
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props)
this.state={
count:0
}
}
onChange=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.value)
this.setState({count:parseInt(e.target.value)})
}
up=()=>{
this.setState({count:this.state.count +1})
}
down=()=>{
this.setState({count:this.state.count -1})
}
render(){
return(
<>
<input type="number" name="inputbox" value={this.state.count} onChange={this.onChange} />
<button onClick={this.up}>+</button>
<button onClick={this.down}>-</button>
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
React 구구단 만들기 배열에 담아 뿌리기
App - 큰 틀
GuguForm - 구구단 form
input box + button
GuguList - 구구단 뿌리는 곳
1. App, GuguForm, GuguList 큰 화면 만들기 + 연결하기
App -> GuguForm -> GuguList
<body>
<div id="root"></div>
<script type="text/babel">
class GuguList extends React.Component{
render(){
return(
<>
<li>2*1=2</li>
<li>2*1=2</li>
<li>2*1=2</li>
<li>2*1=2</li>
</>
)
}
}
class GuguForm extends React.Component{
render(){
return(
<>
<li>
<h2>React 구구단 입니다 ! </h2>
<form>
<input type="number" placeholder="1~9사이의 수를 입력해주세요"/>
<input type="submit" value="클맄"/>
</form>
</li>
<GuguList />
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
}
}
render(){
return(
<>
<ul>
<GuguForm />
</ul>
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
2. submit 버튼 (클맄) 눌러야 GuguList 보이게 만들기
질문 : onClick form에 있는 이유 ? input submit도 작동은 된다.
<body>
<div id="root"></div>
<script type="text/babel">
class GuguList extends React.Component {
render() {
return (
<>
<li>2*2=4</li>
<li>2*2=4</li>
<li>2*2=4</li>
</>
)
}
}
class GuguForm extends React.Component {
render() {
return (
<>
<li>
<h2>React 구구단 </h2>
<form onClick={this.props.sub}>
<input type="number" placeholder="1~9를 입력해주세요!" />
<input type="submit" value="클맄" />
</form>
</li>
{this.props.isSubmit ? <GuguList /> : '입력 해보세오'}
</>
)
}
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isSubmit:false,
}
}
submit=(e)=>{
e.preventDefault()
this.setState({isSubmit:true})
}
render() {
return (
<ul>
<GuguForm
isSubmit={this.state.isSubmit}
sub={this.submit}
/>
</ul>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
form onClick={this.submit} 부분 e 찍어보기
** input box 에 name 을 주고 (gugu) 그 name 명을 찍고 value 를 해야 나온다. !
<li>
<h2>React 구구단 입니다 ! </h2>
<form onSubmit={this.props.submit}>
<input type="number" name="gugu" placeholder="1~9사이의 수를 입력해주세요"/>
<input type="submit" value="클맄"/>
</form>
</li>
submit=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.gugu)
console.log(e.target.gugu.value)
e.preventDefault(e)
this.setState({isSubmit:true})
}
* 아까 위에서 onChange Event 에서는 name이 필요 없었음!
3. input box에 받은 숫자를 App 으로 전달해보기 -> GuguList까지 전달 하기
App state = gugu추가
<body>
<div id="root"></div>
<script type="text/babel">
class GuguList extends React.Component{
render(){
return(
<>
<li>{this.props.gugu}단 입니다.</li>
<li>2*1=2</li>
<li>2*1=2</li>
<li>2*1=2</li>
<li>2*1=2</li>
</>
)
}
}
class GuguForm extends React.Component{
render(){
return(
<>
<li>
<h2>React 구구단 입니다 ! </h2>
<form onSubmit={this.props.submit}>
<input type="number" name="gugu" placeholder="1~9사이의 수를 입력해주세요"/>
<input type="submit" value="클맄"/>
</form>
</li>
{this.props.isSubmit ? <GuguList gugu={this.props.gugu} /> : '숫자를 입력해 보세요!' }
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
isSubmit:false,
gugu:0
}
}
submit=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.gugu)
console.log(e.target.gugu.value)
e.preventDefault(e)
this.setState({
isSubmit:true,
gugu:e.target.gugu.value
})
}
render(){
return(
<>
<ul>
<GuguForm
isSubmit={this.state.isSubmit}
submit = {this.submit}
gugu = {this.state.gugu}
/>
</ul>
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
4. Map 을 통해 구구단 반복하기
class GuguList extends React.Component{
renderList(n){
console.log( typeof n) // string
let g = parseInt(n)
let arr = Array(9).fill(null)
console.log(arr)
return(
arr.map((v,k)=>{
return <li>{g}*{k+1}={g*(k+1)}</li>
})
)
}
render(){
return(
<>
<li>{this.props.gugu}단 입니다.</li>
<li>{this.renderList(this.props.gugu)}</li>
</>
)
}
}
-> 구구단은 잘 나오지만 key값이 없다는 오류 메세지가 뜸 ! (첫번째 오류) -> key값 넣기
-> li tag 에 오류 ! - >제거
질문 : 아래 오류 코드 두번 째 정확한 이유는 !?
* n 으로 받은 인자값 은 STRING !
전체 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Practice</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
ul,
li {
list-style: none;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class GuguList extends React.Component{
renderList(n){
console.log( typeof n) // string
let g = parseInt(n)
let arr = Array(9).fill(null)
console.log(arr)
return(
arr.map((v,k)=>{
return <li key={k}>{g}*{k+1}={g*(k+1)}</li>
})
)
}
render(){
return(
<>
<li>{this.props.gugu}단 입니다.</li>
{this.renderList(this.props.gugu)}
</>
)
}
}
class GuguForm extends React.Component{
render(){
return(
<>
<li>
<h2>React 구구단 입니다 ! </h2>
<form onSubmit={this.props.submit}>
<input type="number" name="gugu" placeholder="1~9사이의 수를 입력해주세요"/>
<input type="submit" value="클맄"/>
</form>
</li>
{this.props.isSubmit ? <GuguList gugu={this.props.gugu} /> : '숫자를 입력해 보세요!' }
</>
)
}
}
class App extends React.Component{
constructor(props){
super(props)
this.state={
isSubmit:false,
gugu:0
}
}
submit=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.gugu)
console.log(e.target.gugu.value)
e.preventDefault(e)
this.setState({
isSubmit:true,
gugu:e.target.gugu.value
})
}
render(){
return(
<>
<ul>
<GuguForm
isSubmit={this.state.isSubmit}
submit = {this.submit}
gugu = {this.state.gugu}
/>
</ul>
</>
)
}
}
ReactDOM.render(
<App />,
document.querySelector('#root')
)
</script>
</body>
</html>
질문1 : 아래 세가지 비교 / 차이 / 흐름(?) 을 모르겟다 / DOM 이 자동으로 변화 계속 감지중 ? 시간은 ??
<script type="text/babel">
class Clock extends React.Component{// 클래스 실행될 때 1 번 실행됨
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
setInterval(()=>{
this.setState({time:new Date().toLocaleTimeString()})
},1000)
}
render(){
console.log('render합니다.')
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
console.log 1초마다 찍힘
<script type="text/babel">
class Clock extends React.Component{ //1
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
}
componentDidMount(){ // render가 완성되었을 때 실행하는 의미 3 ->
// 리액트가 알아서 이 함수를 실행시켜줌 (모든게 render 화면 그려주고 나서 !
// 보통API 연결할 떄 많이 씀
setInterval(()=>{
this.setState({time:new Date().toLocaleTimeString()})
},1000)
}
render(){ // 2
console.log('render합니다.')
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {this.state.time}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
요것도 똑같음
<script type="text/babel">
class Clock extends React.Component{
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
setInterval(()=>{
this.setState({})
},1000)
}
render(){
console.log('render합니다.')
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {new Date().toLocaleTimeString()}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
아래도 같음!
<script type="text/babel">
class Clock extends React.Component{
constructor(props){
super(props)
this.state={
time:new Date().toLocaleTimeString(),
}
}
componentDidMount(){
setInterval(()=>{
this.setState({})
},1000)
}
render(){
console.log('render합니다.')
return(
<div>
<h1>It's Tuesday</h1>
<h2>and now it's {new Date().toLocaleTimeString()}</h2>
</div>
)
}
}
ReactDOM.render(
<Clock />,
document.querySelector('#root')
)
</script>
질문 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Practice</title>
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component{
constructor(props){
super(props)
this.state={
count:0
}
}
onChange=(e)=>{
console.log(e)
console.log(e.target)
console.log(e.target.value)
this.setState({count:e.target.value})
}
up=()=>{
this.setState({count:this.state.count +1})
}
down=()=>{
this.setState({count:this.state.count -1})
}
render(){
return(
<>
<input type="number" name="inputbox" value={this.state.count} onChange={this.onChange} />
<button onClick={this.up}>+</button>
<button onClick={this.down}>-</button>
</>
)
}
}
ReactDOM.render(
<App/>,
document.querySelector('#root')
)
</script>
</body>
</html>
up, down 함수를 익명말고 function 쓰면 안되는지 ?? class안에서는 안됨 ! class문법이 따로잇
질문 3: submit 은 꼭 form ? 안의 것만 보내는건지 = 세팅
class GuguForm extends React.Component {
render() {
return (
<>
<li>
<h2>React 구구단 </h2>
<form>
<input type="number" placeholder="1~9를 입력해주세요!" />
<input type="submit" value="클맄" />
</form>
</li>
<GuguList />
</>
)
}
}
질문 4 : onSubmit form에 있는 이유 ? input submit도 작동은 된다. - > find(질문!) => onSubmit은 form 에 쓴다 !
질문 5 : 두 번째 오류 이유
질문 6 : 아래 코드에서 굳이 Square component가 필요한 이유는 ? 클래스 Board속성값 많을 수도! 그리고 가독성 위해
class Square extends React.Component{
render(){
return(
<button className="square">
{this.props.value}
</button>
)
}
}
class Board extends React.Component{
renderSquare(i){
return(
<Square value={i}/>
)
}
render(){
const status = 'Next Player:X'
return(
<div>
<div className="status">{status}</div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
)
}
}
class Game extends React.Component{
render(){
return(
<div className="game">
<div className="game-board">
<Board />
</div>
<div className="game-ingo">
<div>{/* status */}</div>
<ol>{ /*todo */}</ol>
</div>
</div>
)
}
}
ReactDOM.render(
<Game />,
document.getElementById('root')
)
'블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기' 카테고리의 다른 글
[77일차]20210701 React 댓글 수정 삭제 / 리액트로 생각하기 / 합성과 상속 (0) | 2021.07.01 |
---|---|
[76일차] 20210630 React 리액트 push, children (0) | 2021.06.30 |
[75일차] 20210629 React 리액트 구구단 출력하기 (0) | 2021.06.29 |
[74일차 복습] 리액트란? 리액트 기초 배우기 / React CDN 링크 (0) | 2021.06.28 |
[74일차] 20210628 리액트 react - JSX, ReactDOM (0) | 2021.06.28 |