티스토리 뷰
728x90
1. 지금까지는 모든 파일을 app.js 파일 하나에 다 몰아서 사용했다.
1-1 이 큰 파일을 각 컴포넌트 별로 파일에 넣으면 좀 더 깔끔하게 프로그램을 관리할 수 있다.
import React from 'react'
import ReactDOM from 'react-dom'
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.onRemoveAllClicked = this.onRemoveAllClicked.bind(this)
this.onNextTodoClicked = this.onNextTodoClicked.bind(this)
this.handleAddTodo = this.handleAddTodo.bind(this)
this.state = {
todos: [
"Take your mask",
"Wash your hands",
"Drink more water"
]
}
}
componentDidMount() {
try {
const todos = localStorage.getItem("todos")
if (todos) {
console.log(todos)
this.setState(() => ({ todos: JSON.parse(todos) }))
}
} catch (e) {
}
}
componentDidUpdate(prevProps, prevState) {
if (prevState.todos.length !== this.state.todos.length) {
localStorage.setItem("todos", JSON.stringify(this.state.todos))
}
}
onRemoveAllClicked() {
this.setState(() => {
return {
todos: []
}
})
}
onNextTodoClicked() {
const index = Math.floor(Math.random() * this.state.todos.length)
alert(this.state.todos[index])
}
handleAddTodo(todo) {
if (!todo) {
return 'Please type vaild item'
} else if (this.state.todos.indexOf(todo) > -1) {
return 'Duplicated item typed'
}
this.setState((prevState) => {
return {
todos: prevState.todos.concat(todo)
}
})
}
render() {
// const title = "TO DO List"
return (
<div>
{/* <Header title={title} /> */}
<Header />
<Action
hasTodos={this.state.todos.length > 0}
onNextTodoClicked={this.onNextTodoClicked}
/>
<TodoList
hasTodos={this.state.todos.length > 0}
todos={this.state.todos}
onRemoveAllClicked={this.onRemoveAllClicked}
/>
<AddTodo handleAddTodo={this.handleAddTodo} />
</div>
)
}
}
const Header = (props) => {
return (
<div>
<h1>{props.title}</h1>
</div>
)
}
Header.defaultProps = {
title: 'Your Todo List'
}
const Action = (props) => {
console.log('action performed')
return (
<div>
<button
onClick={props.onNextTodoClicked}
disabled={!props.hasTodos}
>Next Todo?</button>
</div>
)
}
const TodoList = (props) => {
return (
<div>
<button
onClick={props.onRemoveAllClicked}
disabled={!props.hasTodos}
>Remove All</button>
{ props.todos.length === 0 && <p>No Item exists</p> }
{ props.todos.map(todo => <Todo key={todo} todoText={todo} />) }
</div>
)
}
const Todo = (props) => {
return (
<div>
<p>
{propss.todoText}
</p>
</div>
)
}
class AddTodo extends React.Component {
constructor(props) {
super(props)
this.onFormSubmit = this.onFormSubmit.bind(this)
this.state = {
error: undefined
}
}
onFormSubmit(e) {
e.preventDefault()
const typedTodo = e.target.elements.newTodo.value
const error = this.props.handleAddTodo(typedTodo)
this.setState(() => {
return {
error
}
})
if (!error) {
e.target.elements.newTodo.value = ''
}
}
render() {
return (
<div>
{this.state.error && <p>{this.state.error}</p>}
<form onSubmit={this.onFormSubmit}>
<input type="text" name="newTodo" />
<button>Add</button>
</form>
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.getElementById('app'))
2. src 안에 components라는 폴더를 생성하고 각 컴포넌트마다 파일을 생성한다.
2-0 각 분리한 파일에서는 React 컴포넌트를 import 해야 하고, 각 컴포넌트는 export default로 표출한다.
2-1 app.js
import React from 'react'
import ReactDOM from 'react-dom'
import TodoApp from './components/TodpApp'
ReactDOM.render(<TodoApp />, document.getElementById('app'))
2-2 TodoApp.js
import React from 'react'
import Header from './Header'
import Action from './Action'
import TodoList from './TodoList'
import AddTodo from './AddTodo'
export default class TodoApp extends React.Component {
constructor(props) {
super(props)
this.onRemoveAllClicked = this.onRemoveAllClicked.bind(this)
this.onNextTodoClicked = this.onNextTodoClicked.bind(this)
this.handleAddTodo = this.handleAddTodo.bind(this)
this.state = {
todos: [
"Take your mask",
"Wash your hands",
"Drink more water"
]
}
}
componentDidMount() {
try {
const todos = localStorage.getItem("todos")
if (todos) {
console.log(todos)
this.setState(() => ({ todos: JSON.parse(todos) }))
}
} catch (e) {
}
}
componentDidUpdate(prevProps, prevState) {
if (prevState.todos.length !== this.state.todos.length) {
localStorage.setItem("todos", JSON.stringify(this.state.todos))
}
}
onRemoveAllClicked() {
this.setState(() => {
return {
todos: []
}
})
}
onNextTodoClicked() {
const index = Math.floor(Math.random() * this.state.todos.length)
alert(this.state.todos[index])
}
handleAddTodo(todo) {
if (!todo) {
return 'Please type vaild item'
} else if (this.state.todos.indexOf(todo) > -1) {
return 'Duplicated item typed'
}
this.setState((prevState) => {
return {
todos: prevState.todos.concat(todo)
}
})
}
render() {
// const title = "TO DO List"
return (
<div>
{/* <Header title={title} /> */}
<Header />
<Action
hasTodos={this.state.todos.length > 0}
onNextTodoClicked={this.onNextTodoClicked}
/>
<TodoList
hasTodos={this.state.todos.length > 0}
todos={this.state.todos}
onRemoveAllClicked={this.onRemoveAllClicked}
/>
<AddTodo handleAddTodo={this.handleAddTodo} />
</div>
)
}
}
2-3 Header.js
import React from 'react'
const Header = (props) => {
return (
<div>
<h1>{props.title}</h1>
</div>
)
}
Header.defaultProps = {
title: 'Your Todo List'
}
export default Header
2-4 Action.js
import React from 'react'
const Action = (props) => {
console.log('action performed')
return (
<div>
<button
onClick={props.onNextTodoClicked}
disabled={!props.hasTodos}
>Next Todo?</button>
</div>
)
}
export default Action
2-5 TodoList.js
import React from 'react'
import Todo from './Todo'
const TodoList = (props) => {
return (
<div>
<button
onClick={props.onRemoveAllClicked}
disabled={!props.hasTodos}
>Remove All</button>
{ props.todos.length === 0 && <p>No Item exists</p> }
{ props.todos.map(todo => <Todo key={todo} todoText={todo} />) }
</div>
)
}
export default TodoList
2-6 Todo.js
import React from 'react'
const Todo = (props) => {
return (
<div>
<p>
{props.todoText}
</p>
</div>
)
}
export default Todo
2-7 AddTodo.js
import React from 'react'
export default class AddTodo extends React.Component {
constructor(props) {
super(props)
this.onFormSubmit = this.onFormSubmit.bind(this)
this.state = {
error: undefined
}
}
onFormSubmit(e) {
e.preventDefault()
const typedTodo = e.target.elements.newTodo.value
const error = this.props.handleAddTodo(typedTodo)
this.setState(() => {
return {
error
}
})
if (!error) {
e.target.elements.newTodo.value = ''
}
}
render() {
return (
<div>
{this.state.error && <p>{this.state.error}</p>}
<form onSubmit={this.onFormSubmit}>
<input type="text" name="newTodo" />
<button>Add</button>
</form>
</div>
)
}
}
3. 결과 화면
3-1 의미는 없지만 전과 동일하게 잘 동작한다.
728x90
'Client Technologies > React' 카테고리의 다른 글
React : React Modal 사용하기 (0) | 2020.11.16 |
---|---|
React : proposal-class-properties 사용하기 (0) | 2020.10.29 |
React : Webpack dev server 및 소스 맵 사용하기 (0) | 2020.10.28 |
React : webpack으로 React 개발 자동화하기 (0) | 2020.10.28 |
React : node package.json scripts 속성 사용하기 (0) | 2020.10.28 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
- 도커 개발환경 참고
- AWS ARN 구조
- Immuability에 관한 설명
- 자바스크립트 멀티 비동기 함수 호출 참고
- WSDL 참고
- SOAP 컨슈머 참고
- MySql dump 사용법
- AWS Lambda with Addon
- NFC 드라이버 linux 설치
- electron IPC
- mifare classic 강의
- go module 관련 상세한 정보
- C 메모리 찍어보기
- C++ Addon 마이그레이션
- JAX WS Header 관련 stackoverflow
- SOAP Custom Header 설정 참고
- SOAP Custom Header
- SOAP BindingProvider
- dispatcher 사용하여 설정
- vagrant kvm으로 사용하기
- git fork, pull request to the …
- vagrant libvirt bridge network
- python, js의 async, await의 차이
- go JSON struct 생성
- Netflix Kinesis 활용 분석
- docker credential problem
- private subnet에서 outbound IP 확…
- 안드로이드 coroutine
- kotlin with, apply, also 등
- 안드로이드 초기로딩이 안되는 경우
- navigation 데이터 보내기
- 레이스 컨디션 navController
- raylib
TAG
- one-to-many
- 스프링
- 스프링부트
- Spring
- one-to-one
- 매핑
- Security
- 상속
- crud
- form
- XML
- 설정
- mapping
- Rest
- jsp
- Many-To-Many
- RestTemplate
- login
- 자바
- 로그인
- 외부파일
- 설정하기
- MYSQL
- Validation
- WebMvc
- Spring Security
- spring boot
- hibernate
- Angular
- 하이버네이트
250x250