Todo 추가 서비스
Todo 추가를 통해 이벤트 핸들러 함수를 구현하는 방법과 핸들러 함수를 UI에 연결
Todo 추가 모듈 생성
imoprt React from "react";
import {TextField, Paper Button, Grid} from "@material-ui/core";
class AddTodo extends React.Component {
constructor(props) {
super(props);
this.state = {
item : { title : ""}
};
}
render(){
return(
<Paper style={{margin:16, padding: 16}}>
<Grid container>
<Grid xs={11} md={11} item style={{ paddingRight:16 }}>
<TextFiled placeholder="Add Todo here" fullWidth />
</Grid>
<Grid xs={1} md={1} item>
<Button fullWidth color="secondary" variant="outlined">
+
</Button>
</Grid>
</Grid>
</Paper>
)
}
}
export default AddTodo;
App.js에 AddTodo 컴포넌트 추가
import React from 'react';
import Todo from './Todo';
import AddTodo from './AddTodo';
import {Paper, List, Container} from "@material-ui/core";
import './App.css';
class App extends React.Component{
constructor(props){
super(props);
this.state = {
items: [
{ id:"0", title: "Hello World 1", done: true},
{ id: "1", title: "Hello World 2", done: false},
],
};
}
render(){
//자바스크립트가 제공하는 map()을 이용해 배열을 반복해 <Todo /> 컴포넌트 생성
const todoItems = this.state.items.length > 0 &&
(
<Paper style={{margin:16}}>
<List>
{this.state.items.map((item, idx) =>(
<Todo item={item} key={item.id} />
))}
</List>
</Paper>
)
return(
<div className='App'>
<Container maxWidth="md">
<AddTodo />
<div className="TodoList">{todoItems}</div>
</Container>
</div>
)
}
}
export default App;
Add 핸들러 추가
import React from "react";
import {TextField, Paper, Button, Grid} from "@material-ui/core";
class AddTodo extends React.Component{
constructor(props){
super(props);
this.state= { // 사용자의 입려글 저장할 오브젝트
item: { title: ""}
};
this.add = props.add; //props의 함수를 this.add에 연결
}
//함수 작성
onInputChange = (e) => {
const thisItem = this.state.item;
thisItem.title = e.target.value;
this.setState({item : thisItem});
console.log(thisItem);
}
render(){
return(
<Paper style={{margin: 16, padding: 16}}>
<Grid container>
<Grid xs={11} md={11} item style={{paddingRight: 16}}>
<TextField placeholder="Add Todo here"
fullWidth onChange={this.onInputChange}
value={this.state.item.title}
onKeyPress={this.enterKeyEventHandler}/>
</Grid>
<Grid xs={1} md={1} item>
<Button fullWidth color="secondary" variant="outlined" onClick={this.onButtonClick}>
+
</Button>
</Grid>
</Grid>
</Paper>
);
}
}
export default AddTodo;
onInputChange() ???
자바스크립트 함수다. Event e를 매겨변수로 받는다. event 오브젝트는 어떤 일이 일어났을 때의 상태와 event가 발생했을 때 시점의 정보를 담고 있다.
Add 함수 작성
App컴포넌트는 items에 접근이 가능(AddTodo컴포넌트는 상위 컴포넌트의 items에 접근 X)
App컴포넌드에 add() 함수를 추가하고 AddTodo의 프로퍼티로 넘겨 AddTodo에서 사용한다.
import React from 'react';
import Todo from './Todo';
import AddTodo from './AddTodo';
import {Paper, List, Container, AppBar, Toolbar, Grid, Typography, Button} from "@material-ui/core";
import { call, signout } from './service/ApiService';
import './App.css';
class App extends React.Component{
constructor(props){
super(props);
this.state = {
items: [
{ id: "0", title:"Hello World 1", done: true},
{ id: "1", title:"Hello World 2", done: false},
],
};
}
함수 추가
add = (item) => {
const thisItem = this.state.items;
item.id = "ID-" + thisItem. ; // 키를 위한 id추가
item.don = false;//done 초기화
thisItem.push(item); // 리스트에 아이템 추가
this.setState({ item : thisItem }); //업데이트는 반드시 this.setState로 해야함
console.log("item : ", this.state.items);
}
render(){
//자바스크립트가 제공하는 map()을 이용해 배열을 반복해 <Todo /> 컴포넌트 생성
const todoItems = this.state.items.length > 0 &&
(
<Paper style={{margin:16}}>
<List>
{this.state.items.map((item, idx) =>(
<Todo item={item} key={item.id} />
))}
</List>
</Paper>
)
// 선택한 content 렌더링
return(
<div className='App'>
<Container maxWidth="md">
<AddTodo add={this.add}/>
<div className="TodoList">{todoItems}</div>
<Container>
</div>
);
}
}
export default App;
AddTodo.js에서 add함수 사용 및 Enter키 입력 시 아이템 추가
import React from "react";
import {TextField, Paper, Button, Grid} from "@material-ui/core";
class AddTodo extends React.Component{
constructor(props){
super(props);
this.state= { // 사용자의 입려글 저장할 오브젝트
item: { title: ""}
};
this.add = props.add; //props의 함수를 this.add에 연결
}
//함수 작성
onInputChange = (e) => {
const thisItem = this.state.item;
thisItem.title = e.target.value;
this.setState({item : thisItem});
console.log(thisItem);
}
// 함수 작성 클릭
onButtonClick = () => {
this.add(this.state.item); // add 함수 사용
this.setState({
item:{title:""}
});
}
enterKeyEventHandler = (e) => {
if(e.key === "Enter") this.onButtonClick();
}
render(){
return(
<Paper style={{margin: 16, padding: 16}}>
<Grid container>
<Grid xs={11} md={11} item style={{paddingRight: 16}}>
<TextField placeholder="Add Todo here"
fullWidth onChange={this.onInputChange}
value={this.state.item.title}
onKeyPress={this.enterKeyEventHandler}/>
</Grid>
<Grid xs={1} md={1} item>
<Button fullWidth color="secondary" variant="outlined" onClick={this.onButtonClick}>
+
</Button>
</Grid>
</Grid>
</Paper>
);
}
}
export default AddTodo;
onKeyPress()는 키보드의 키가 누릴 때마다 실행되는 이벤트 핸들러다.
Todo 삭제
material-ui 컴포넌트 import
import { ListItem, ListItemText, InputBase, Checkbox, ListItemSecondaryAction, IconButton } from "@material-ui/core"; import DeleteOutlined from "@material-ui/icons/DeleteOutlined"
Todo.js에서 삭제 버튼 추가
import React from "react";
import {ListItem,
ListItemText,
InputBase,
Checkbox,
ListItemSecondaryAction,
IconButton} from "@material-ui/core";
import DeleteOutlined from "@material-ui/icons/DeleteOutlined";
class Todo extends React.Component {
render() {
const item = this.state.item;
return(
<ListItem>
<Checkbox checked={item.done} disableRipple />
<ListItemText>
<InputBase
inputProps={{"aria-label" : "naked"}
onClick={this.offReadOnlyMode}
type="text"
id={item.id} //각 리스트를 구분하려고 id를 연결
name={item.id} //각 리스트를 구분하려고 id를 연결
value={item.title || ''}
multiline={true}
fullWidth={true}
onChange={this.editEventHandler}
onKeyPress={this.enterKeyEventHanlder}
/>
</ListItemText>
<ListItemSecondaryAction>
<IconButton aria-label="Delete Todo" onClick={this.deleteEventHandler}>
<DeleteOutlined />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
);
}
}
export default Todo;
App.js에서 delete() 함수 작성
//삭제 함수
delete = (item) => {
const thisItem = this.state.items;
console.log("Before Update Items : ", this.state.items)
const newItems = thisItem.filter(e => e.id !== item.id);
this.setState({items: newItems}, () => {
// 디버깅 콜백
console.log("Update Items : ", this.state.items);
});
}
App.js에서 Todo의 delete에 연결
//자바스크립트가 제공하는 map()을 이용해 배열을 반복해 <Todo /> 컴포넌트 생성
const todoItems = this.state.items.length > 0 &&
(
<Paper style={{margin:16}}>
<List>
{this.state.items.map((item, idx) =>(
<Todo item={item} key={item.id} delete={this.delete} />
))}
</List>
</Paper>
)
Todo.js에 delete 함수 사용
constructor(props){
... 생략
this.delete = props.delete;
}
//삭제
deleteEventHandler = () => {
this.delete(this.state.item);
}
<ListItemSecondaryAction>
<IconButton aria-label="Delete Todo" onClick={this.deleteEventHandler}>
<DeleteOutlined />
</IconButton>
</ListItemSecondaryAction>
마무리
Todo리스트에 관한 서비스를 만드는 코드를 작성 했습니다. 수정관련된 코드는 생략 하겠습니다.
'개발 > 도서' 카테고리의 다른 글
TodoList 프론트엔드 서비스 개발 - 1 (0) | 2022.08.25 |
---|---|
React.js - 프론트엔드 개발 (0) | 2022.08.18 |
Todo 서비스 구현(REST API) (0) | 2022.08.16 |
백엔드 서비스 아키텍처 - 2 (0) | 2022.08.10 |
백엔드 서비스 아키텍처 (0) | 2022.08.08 |