일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- 아이디어 #앱아이디어 #건축 #현장관리어플
- 나머지 매개변수
- 객체
- Visual Studio Code Shortcut for windows
- 혼자공부하는자바스크립트
- 문자자료형
- 폴로스타일니트
- 일급객체(함수)
- 항해99
- 2023나만의버킷리스트만들기
- 자바
- 비쥬얼 스튜디오 코드 프로그램 단축키(윈도우)
- 숫자자료형
- 조건문
- 자바뽀개기
- 책리뷰
- 함수
- 랑과나의사막
- 자바스크립트
- 스파르타코딩클럽
- 항해99사전강의
- 유령의마음으로
- 혼공자스
- 봄날스웨터
- 배열의 요소로 함수 할당
- BomNalSweater
- 배열
- 불자료형
- 탬플릿문자열
- 스코프 및 화살표 함수
- Today
- Total
하고 싶은게 많음
[혼공자스] 10. 리액트 라이브러리 맛보기 본문
리액트 라이브러리 : 규모가 큰 자바스크립트 라이브러리. 사용자 인터페이스를 쉽게 구성할 수 있도록 도와줌.
리액트 라이브러리 사용 준비하기
https://unpkg.com/react@17/umd/react.development.js
https://unpkg.com/react-dom@17/umd/react-dom.development.js
https://unpkg.com/babel-standalone@6/babel.min.js
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<!--리액트를 사용하는 코드 입력-->
<script type ="text/babel"></script>
</body>
</html>
리액트 라이브러리는 단순한 자바스크립트가 아니라 리액트를 위해서 개발된 자바스크립트 확장 문법을 사용. 이러한 문
법을 사용하려면 바벨babel이라는 라이브러리를 추가로 읽어들이고 바벨을 적용할 부분을 지정해야한다.
루트 컴포넌트 출력하기
컴포넌트 component " 리액트에서 화면에 출력되는 요소 "
루프 컴포넌트 root component " 컴포넌트 중 가장 최상위에 배치하는 컴포넌트 "
리액트는 컴포넌트를 만들 떼 HTML요소를 만드는 것과 동일한 문법을 사용.
컴포넌트 생성하기
<컴포넌트 이름></컴포넌트 f이름>
생성한 컴포넌트를 출력할 때는 ReactDOM.render( ) 메소드 사용.
컨테이너 container " 컴포넌트를 출력할 상자 "
컨포넌트 출력하기
ReactDOM.render(컴포넌트, 컨테이너)
//루트 컴포넌트 출력하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//컴포넌트와 컨테이너 생성하기
const component = <h1>리액트 기본</h1>
const container = document.getElementById('root')
//출력
ReactDOM.render(component, container)
</script>
</body>
</html>
ㄴh1컴포넌트를 생성하고, h1컴포넌트를 출력할 div#root를 읽어들인 뒤, ReactDOM.render( ) 메소드로 컴포넌트를 div#root에 출력. 만약 div#root를 선언하지 않았다면 화면에는 아무 것도 뜨지않았을거임.
자바 스크립트 코드 내부에 HTML 코드를 사용한 모습을 볼 수 있는데 이러한 문법은 JSX(자바스크칩트 확장 문법)이라고함. 웹 브라우저는 사실 이러한 코드를 읽고 실행하지 못한다. 바벨이 JSX 코드를 읽고 일반적인 자바스크립트 문법으로 변환한 뒤 실행해주므로 이러한 코드가 사용 가능한 것.
바벨 공식 홈페이지에서 바벨 REPL도구를 사용하면 바벨이 어떤 식으로 코드를 바꾸는지 확인 가능
Babel · The compiler for next generation JavaScript
The compiler for next generation JavaScript
babeljs.io
JSX(JavaScripteXtension) 기본 문법
표현식 출력하기
<태그>{표현식}</태그>
<태그 속성 = {표현식} />
※ 다만, 속성으로 표현식을 출력할 때는 따옴표를 사용하면 안됨.
//표현식 출력하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//상수 선언
const name = '구름'
const imgUrl = 'http://placedog.net/400/200'
//컴포넌트와 컨테이너 생성
const component = <div>
<h1>{name} 님 안녕하세요! </h1>
<img src = {imgUrl} />
</div>
const container = document.getElementById('root')
//출력
ReactDOM.render(component, container)
</script>
</body>
</html>
클래스 컴포넌트
React사용 시
this.state: 화면에 출력할 건 this.state로 지정
setState: 변경할 때 사용
ComponentDidMount : 추가될 때 사용
ComponentWillUnmount : 화면에서 제거할 때 사용
HTML 표준에 포함된 태그로 컴포넌트를 만들 수 있지만, 사용자가 직접 클래스 또는 함수를 이용해 컴포넌트를 만들 수 있음.
클래스 컴포넌트: 클래스로 만드는 컴포넌트
함수 컴포넌트: 함수로 만드는 컴포넌트
클래스 컴포넌트 만들기
class 컴포넌트 이름 extends React.Component {
render ( ) {
return <h1> 출력할 것 </h1>
}
}
React.Component 클래스의 상속을 받아야 컴포넌트로 동작할 수 있게 하는 속성과 메소드를 받을 수 있음. React.Component 클래스는 화면에 무언가를 출력할 때 render( ) 메소드를 호출함. 이를 오버라이드해서 원하는 것을 출력함.
//루프 컴포넌트 출력을 클래스 컴포넌트로 구현하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//애플리케이션 클래스 생성
class App extends React.Component {
render () {
return <h1>리액트 기본</h1>
}
}
//출력
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
클래스 컴포넌트를 사용하면 클래스 메소드 내부에서 this.props 속성을 사용할 수 있었음. 이 속성은 컴포넌트를 선언할 때 전달함.
//컴포넌트의 속성 사용하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//애플리케이션 클래스 생성
class App extends React.Component {
render () {
return <div>
<h1>{this.props.name} 님 안녕하세요!</h1>
<img src = {this.props.imgUrl} />
</div>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App name = "쏘매띵" imgUrl = "http://placedog.net/400/200" />,
container)
</script>
</body>
</html>
컴포넌트의 기본적인 속성과 메소드 436
클래스의 메소드 오버라이드 하기
class App extends React.Component {
constructor (props) {
super(props)
//생성자 코드
}
render() {
//출력할 것
}
componentDidMount () {
//컴포넌트가 화면에 출력될 때 호출
}
componentWillUnmount() {
//컴포넌트가 화면에서 제거될 때 호출
}
}
우리가 변경해서 사용하는 속성으로는 state속성이 있음. state속성에는 출력할 값을 저장을 하는데 속성 값을 변경할 때는 반드시 setState( ) 메소드를 사용해야함.
setState( ) 메소드로 속성의 값을 변경하면 컴포넌트는 render( )메소드를 호출해서 화면에 변경 사항을 출력함.
//상태 선언하기 (생성자 위치)
this.state = { 속성 : 값 }
//상태 변경하기(이외의 위치)
this.setState ( { 변경할 속성 : 값 } )
//이벤트 연결하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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
}
this.countUp = this.countUp.bind(this)
}
render() {
return <div>
<h1>클릭한 횟수: {this.state.count}</h1>
<button onClick = {this.countUp}>클릭</button>
</div>
}
countUp (event) {
this.setState({
count: this.state.count + 1
})
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
※ 대문자 소문자 잘 보고 작성해야한다! 안그럼 오류남! 리액트에서 JSX문법으로 이벤트를 연결할 때는 대소문자를 확실히 지켜서 입력해줘야함
리액트 이벤트 이름을 확인할 수 있는 주소
https://ko.reactjs.org/docs/events.html#clipboard-events
합성 이벤트(SyntheticEvent) – React
A JavaScript library for building user interfaces
ko.reactjs.org
//이벤트 연결하기: 다른 this 바인드 방법(1)
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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
}
}
render() {
return <div>
<h1>클릭한 횟수: {this.state.count}</h1>
<button onClick = {(e) => this.countUp(e)}>클릭</button>
</div>
}
countUp (event) {
this.setState({
count: this.state.count + 1
})
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
결과는 위와 같음
//이벤트 연결하기: 다른 this 바인드 방법(2)
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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
}
}
render() {
return <div>
<h1>클릭한 횟수: {this.state.count}</h1>
<button onClick = {this.countUp}>클릭</button>
</div>
}
countUp = (event) => {
this.setState({
count: this.state.count + 1
})
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
결과는 위와 같음
//입력 양식 사용하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
text: ''
}
this.handleChange = this.handleChange.bind(this)
}
render() {
return <div>
<input
value = {this.state.text}
onChange = {this.handleChange} />
<h1>{this.state.text}</h1>
</div>
}
handleChange (event) {
this.setState({
text: event.target.value
})
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
스타일 지정하기
스타일을 지정할 때는 style 속성에 객체를 지정.
render ( ) {
const style = { }
return <h1 style = {style} 글자 </h1>
}
CSS 스타일 속성 이름 | 가능한 형태(1) | 가능한 형태(2) |
color : red | { color: 'red' } |
{ 'color' : 'red' } |
font-size : 2px | { fontSize: 2 } |
{ 'font-size' : 2 } |
크기 등의 단위는 숫자만 입력하면 됨. px를 붙이지 않아도 괜춘.
//체크 상태에 따라서 스타일 지정하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
checked: false
}
this.handleClick = this.handleClick.bind(this)
}
render() {
const textStyle = {
colo : this.state.checked ? 'blue' : 'red'
}
return <div>
<input
type = "checkbox"
onClick = {this.handleClick} />
<h1 style = {textStyle}>글자</h1>
</div>
}
handleClick (event) {
this.setState({
checked : event.target.checked
})
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
컴포넌트 배열
리액트는 컴포넌트를 요소로 갖는 배열을 사용해서 한 번에 여러 개의 컴포넌트를 출력할 수 있음.
//컴포넌트 배열 사용하기(1)
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//애플리케이션 클래스 생성
class App extends React.Component {
render () {
const list = [
<li>사과</li>,
<li>바나나</li>,
<li>배</li>,
<li>귤</li>
]
return <ul>{list}</ul>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
//컴포넌트 배열 사용하기(2)
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
fruits: ['사과','바나나','배','귤']
}
}
render () {
//항목을 생성
const list = this.state.fruits.map((item) => {
return <li>{item}</li>
})
//출력
return <ul>{list}</ul>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
결과는 위의 코드와 같음.
//컴포넌트 배열 사용하기(3)
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
fruits: ['사과','바나나','배','귤']
}
}
render () {
return <ul>{
this.state.fruits.map((item)=> {
return <li>{item}</li>
})
}</ul>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
결과는 위의 코드와 같음.
리앤트와 데이터
여러 개의 컴포넌트 사용하기
//Item 컴포넌트 만들기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//애플리케이션 클래스 생성
class App extends React.Component {
render () {
return <ul>
<Item />
<Item />
<Item />
</ul>
}
}
class Item extends React.Component {
render () {
return <li>Item 컴포넌트 </li>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
App컴포넌트에서 Item 컴포넌트로 어떤 데이터를 전달하고 싶을 때는 컴포넌트의 속성을 사용함.
//Item 컴포넌트에 속성 전달하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id ="root"></div>
<script type ="text/babel">
//애플리케이션 클래스 생성
class App extends React.Component {
render () {
return <ul>
<Item value = "Item 컴포넌트 1번" />
<Item value = "Item 컴포넌트 2번" />
<Item value = "Item 컴포넌트 3번" />
</ul>
}
}
class Item extends React.Component {
constructor(props) {
super(props)
}
render () {
return <li>{this.props.value}</li>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
App 컴포넌트에서 Item 컴포넌트로 value속성을 전달하고, Item 컴포넌트에서 value속성을 출력하는 예임.
부모에서 자식의 state 속성 변경하기
//부모에서 자식의 state 속성 변경하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
time: new Date()
}
}
componentDidMoundt () {
//컴포넌트가 화면에 출력되었을 때
this.timeId = setInterval(() => {
this.setState({
time:new Date()
})
}, 1000)
}
ComponentWillUnmount() {
//컴포넌트가 화면에서 제거될 때
clearInterval(this.timerId)
}
render() {
return <ul>
<Item value = {this.state.time.toLocaleString()} />
<Item value = {this.state.time.toLocaleString()} />
<Item value = {this.state.time.toLocaleString()} />
</ul>
}
}
class Item extends React.Component {
constructor (props) {
super(props)
this.state = {
value: props.value
}
}
componentDidUpdate (prevProps) {
if (prevProps.value !== this. props.value) {
this.setState ({
value: this.props.value
})
}
}
render() {
return <li>{this.state.value}</li>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
ㄴ componentDidUpdate( )메소드는 컴포넌트에 변경이 발생했을 때 호출되는 메소드로 이를 오버라이드해서 사용하고 있음. componentDidUpdate( ) 메소드는 매개변수로 변경 이전의 속성(prevProps)이 들어오며, 이 속성 값과 현재 속성 값을 비교해서 변경이 있는경우에만 setState( )메소드를 호출해서 화면에 변경사항을 출력. componentDidUpdate( ) 메소드 부분이 없음녀 시간은 변하지 않음.
자식에서 부모의 state 속성 변경하기
반대로 자식 컴포넌트에서 부모 컴포넌트의 상태를 변경 할 때는 메소드를 사용. 부모 컴포넌트에서 자신(부모)의 속성을 변경하는 메소드를 자식에게 전달한 뒤,
자식에서 이를 호출하게 만드는 것임.
//자식에서 부모의 state 속성 변경하기
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = {
value : ''
}
this.changeParent = this.changeParent.bind(this)
}
render () {
return <div>
<CustomInput onChange = {this.changeParent} />
<h1>{this.state.value}</h1>
</div>
}
changeParent (event) {
this.setState ({
value : event.target.value
})
}
}
class CustomInput extends React.Component {
render () {
return <div>
<input onChange = {this.props.onChange} />
</div>
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
예제1) 리액트로 만드는 할 일 목록 애플리케이션
<!DOCTYPE html>
<html>
<head>
<title>Document</title>
<!--리액트 사용 준비-->
<script src = "https://unpkg.com/react@17/umd/react.development.js"></script>
<script src = "https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src = "https://unpkg.com/babel-standalone@6/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 = this.load()
//메소드 바인드
this.textChange = this.textChange.bind(this)
this.textKeyDown = this.textKeyDown.bind(this)
this.buttonClick = this.buttonClick.bind(this)
this.removeItem = this.removeItem.bind(this)
this.changeCheckData = this.changeCheckData.bind(this)
}
save () {
localStorage.state = JSON.stringify(this.state)
}
load () {
let output
try { output = JSON.parse(localStorage.state)
} catch (e) {}
if (output !== undefined
&& output.keyCount !== undefined
&& output.currentValue !== undefined)
{
output = JSON.parse(localStorage.state)
} else {
output = {
keyCount : 0,
currentValue : '',
todos: []
}
}
return output
}
componentDidUpdate() {
this.save()
}
render () {
return <div>
<h1>할 일 목록</h1>
<Input
value = {this.state.currentValue}
onChange = {this.textChange}
onKeyDown = {this.textKeyDown}/>
<button onClick = {this.buttonClick}>추가하기</button>
<div>
{this.state.todos.map((todo)=> {
return <TodoItem
dataKey = {todo.key}
isDone = {todo.isDone}
text = {todo.text}
removeItem = {this.removeItem}
changeCheckData = {this.chagngeCheckData} />
})}
</div>
</div>
}
textChange (event) {
this.setState({
currentValue: event.target.value
})
}
textKeyDown (event) {
const ENTER = 13
if (event.keyCode === ENTER) {
this.buttonClick()
}
}
buttonClick (event) {
if (this.state.currentValue.trim() !== '') {
this.setState ({
todos: [...this.state.todos, {
key: this.state.keyCount.toStirng(),
isDone: false,
text: this.state.currentValue
}]
})
this.state.keyCount += 1
this.state.currentValue = ''
}
}
removeItem(key) {
this.setState({
todos: this.state.todos.filter((todo) => {
return todo.key !== key
})
})
}
changeCheckData (key, changed) {
let target = [...this.state.todos]
target.filter((todo) => todo.key === key)[0].isDone = changed
this.setState({
todos: target
})
}
}
class TodoItem extends React.Component {
constructor (props) {
super(props)
this.state = {
isDone: props.isDone
}
this.checkboxClick = this.checkboxClick.bind(this)
}
render () {
const textStyle = {}
textStyle.textDecoration
= this.state.isDone ? 'line-through' : ''
return (
<div style = {textStyle}>
<Input
type = "checkbox"
checked = {this.state.isDone}
onChange = {this.checkboxClick} />
<span>{this.props.text}</span>
<button onClick={() => this.props.removeItem(this.props.dataKey)}>제거</button>
</div>
)
}
checkboxClick () {
const changed = !this.state.isDone
this.props.changeCheckData(this.props.dataKey, changed)
}
componentDidUpdate(prevProps) {
if (prevProps.isDone !== this.props.isDone) {
this.setState ({
isDone: this.props.isDone
})
}
}
}
//출력하기
const container = document.getElementById('root')
ReactDOM.render(<App />, container)
</script>
</body>
</html>
책보고 친건데...몇 번을 봐도 오류가 뜬다...좀 더 찾아봐야겠다
'IT > 자바스크립트' 카테고리의 다른 글
[혼공자스]09.클래스 (0) | 2022.12.05 |
---|---|
[혼공자스] 08. 예외처리 (0) | 2022.12.05 |
[혼공자스] 07.문서 객체 모델 (0) | 2022.12.05 |
[혼공자스] 06. 객체 (0) | 2022.11.18 |
자바스크립트 실수 모음집 (0) | 2022.11.18 |