
import {useReducer, useRef, useCallback} from "react";
import ContactEditor from "./components/ContactEditor";
import ContactList from "./components/ContactList";
import "./App.css";
const mockData = [
{
id: 0,
name: "박아무개",
content: "010-2345-2323",
},
{
id: 1,
name: "홍길동",
content: "031-232-2323",
},
];
function reducer (state, action){
switch (action.type){
case "CREATE":
return[action.data, ...state];
case "DELETE":
return state.filter((contact)=>contact.id !== action.targetId);
default:
return state;
}
}
function App() {
const [contacts, dispatch] = useReducer(reducer, mockData);
const idRef= useRef("3");
const onCreate = useCallback((name, content) => {
dispatch({
type: "CREATE",
data: {
id: idRef.current++,
name: name,
content: content,
}
})
}, []);
const onDelete = useCallback((targetId) => {
dispatch({
type: "DELETE",
targetId: targetId,
})
}, []);
return (
<div className="App">
<h2>Contact List</h2>
<section>
<ContactEditor
onCreate={onCreate}
/>
</section>
<section>
<ContactList
contacts={contacts}
onCreate={onCreate}
onDelete={onDelete}
/>
</section>
</div>
);
}
export default App;
import React, {useRef, useState, memo} from "react";
import "./ContactEditor.css";
const ContactEditor = ({ onCreate }) => {
const [name, setName] = useState("");
const [content, setContent] = useState("");
const nameRef = useRef();
const contentRef = useRef();
const onSubmit = () => {
if(name === ""){
nameRef.current.focus();
return;
}
if(content === ""){
contentRef.current.focus();
return;
}
onCreate(name, content)
}
const onChangeName = (e) => {
setName(e.target.value);
}
const onChangeContent = (e) => {
setContent(e.target.value);
}
const onKeyDown = (e) => {
if (e.keyCode === 13) {
onSubmit();
}
}
return (
<div className="ContactEditor">
<div className="title">Add Contact</div>
<div className="input_wrapper">
<input className="name" placeholder="이름 ..."
ref={nameRef}
value={name}
onChange={onChangeName}
/>
<input className="contact" placeholder="연락처(이메일) ..."
ref={contentRef}
value={content}
onChange={onChangeContent}
onKeyDown={onKeyDown}
/>
</div>
<button onClick={onSubmit}>Add</button>
</div>
);
}
export default memo(ContactEditor);
import React, {memo} from "react";
import "./ContactItem.css";
const ContactItem = ({ id, name, content, onDelete }) => {
const onClickDeleteButton = () =>{
onDelete(id);
}
return (
<div className="ContactItem">
<div className="name">{name}</div>
<div className="contact">{content}</div>
<button onClick={onClickDeleteButton}>🗑️ Remove</button>
</div>
);
}
export default memo(ContactItem);
import "./ContactList.css";
import ContactItem from "./ContactItem";
export default function ContactList({ contacts, onDelete }) {
return (
<div className="ContactList">
<div className="title">Contact List</div>
{contacts.map((contact, id)=> {
return(
<ContactItem
key={id}
{...contact}
onDelete={onDelete}
/>
)
})}
</div>
);
}
설명은 나중에..