2022. 11. 10. 23:22ㆍReact/React Hook
예제는 아주 간단한 예제이지만 처음에 React를 접하고 나서 잘 이해가 가지 않았지만 몇번을 보고 나서는 이해 하게 되었다. 특히 앞선 클로저를 이해하고 나서는 왜 변경함수를 통하여 현재 상태값을 변경하는지도 이해하기 쉬웠던거 같다.
비록 간단한 예제 이지만 처음으로 React를 접하는 분들에게는 꼭 useState를 잘 이해하기를 바랍니다.
전체적인 컴포넌트 구조는 아래와 같다.
위의 화면은 Todo 예제 전체 컴포넌트 구조 이다. 부모 컴포넌트는 Todo 이고 자식 컴포넌트는 TodoForm, TodoList 로 구성 된다.
[Todo.jsx]
import React, { useState } from "react";
import TodoForm from "./TodoForm.";
import TodoList from "./TodoList";
const Todo = () => {
// Todo 목록 설정
const [userTodos, setUserTodos ] = useState([]);
// ① Todo 항목 추가
const addTodoHandler = (todo) => {
setUserTodos(prevTodos => [
...prevTodos,
{ id: Math.random().toString(), ...todo},
]);
}
// ② Todo 항목 삭제
const removeTodoHandler = todoId => {
setUserTodos(prevTodos =>
prevTodos.filter(todo => todo.id !== todoId)
);
};
return (
<div className="h-100 w-full flex items-center justify-center">
<div className="p-4 m-4 w-full lg:w-3/4 lg:max-w-3xl">
<TodoForm onAddTodo={addTodoHandler} />
<section>
<TodoList todos={userTodos} onRemoveItem={removeTodoHandler} />
</section>
</div>
</div>
);
};
export default Todo;
① addToHandler(Todo 항목 추가)
setUserTodos 변경함수 파라미터에 [가장최근상태값,사용자가입력한값] 값으로 목록값을 갱신한다.
② removeTodoHandler (Todo 항목 삭제)
setUserTodos 변경함수에서 현재상태값에서 TodoList에서 전달받은 id값을 제외한 값으로 목록값을 갱신한다.
Todo 등록하기
입력한 내용은 아래 그림과 같이 Todo(부모) 컴포넌트에서 props 속성으로 onAddTodo 를 전달하게 되고 ① TodoForm(자식) 컴포넌트에서는 아래 그림에서 보듯이 props.onAddTodo(전달값/객체) 를 호출 하게 되고 ② Todo(부모) 컴포넌트에서는 addToHandler 함수를 호출 하여 입력 값을 처리 한다.
[TodoForm.jsx]
import React, { useState } from "react";
const TodoForm = (props) => {
const [ enteredTodo, setEnteredTodo ] = useState('');
const submitHandler = (event) => {
event.preventDefault();
props.onAddTodo({content: enteredTodo});
setEnteredTodo('');
}
return (
<>
<div>
<h1 className="inline-block text-2xl sm:text-3xl font-extrabold text-slate-900 tracking-tight dark:text-slate-200">
Todo List
</h1>
</div>
<form onSubmit={submitHandler}>
<div className="flex mt-6">
<input
type="text"
className="shadow-md shadow-blue-200/40 md:shadow-indigo-200/40 border rounded w-full py-2 px-3 mr-2"
placeholder="Add Todo"
id="todo"
value={enteredTodo}
onChange={event => {
setEnteredTodo(event.target.value);
}}
/>
<button className="bg-rose-500 hover:bg-rose-700 text-white font-bold py-2 px-4 border border-rose-700 rounded">
ADD
</button>
</div>
</form>
</>
);
};
export default TodoForm;
위의 코드에서 사용자가 입력한 값이 어떻게 Todo(부모) 컴포넌트에게 전달되는지 보자
- input 태그에서 사용자가 글을 입력 할때마다 onChange 이벤트 호출
- onChage 이벤트 호출 시 setEnteredTodo 상태변경함수를 호출 하여서 사용자가 입력한 내용을 현재상태 값으로 저장한다.
- Add 버튼 클릭 시 submitHandler 함수를 호출한다.
- submitHandler 함수에서는 props.onAddTodo({입력값}) 통하여 Todo(부모) 컴포넌의 addToHandler 함수를 통하여 입력 값을 처리한다.
Todo 목록
Todo(부모) 컴포넌트에서 전달받은 Todo 목록 데이터를 Redering 처리한다.
[TodoList.jsx]
import React, { useState } from "react";
import ClearIcon from "@mui/icons-material/Clear";
import DoneIcon from "@mui/icons-material/Done";
const TodoList = (props) => {
const [ taskCss, setTaskCss ] = useState('inline-block mt-1 text-md text-slate-900');
const [ taskDone, setTaskDone ] = useState(false);
// Done event 처리 함수
const doneHandler = () => {
setTaskDone(!taskDone);
if (taskDone) {
setTaskCss('mt-1 text-md text-rose-900 line-through');
}
else {
setTaskCss('mt-1 text-md text-slate-900');
}
};
return (
<ul className="list-none mt-3">
{props.todos.map(todo => (
<li
key={todo.id}
className="flex items-center justify-between px-2 py-3 border-b"
>
<div>
<p className={taskCss}>{todo.content}</p>
</div>
<div>
<ClearIcon
style={{ color: "red" }}
onClick={props.onRemoveItem.bind(this, todo.id)}
className="cursor-pointer"
/> // ① Todo내용 삭제
<DoneIcon
style={{ color: "darkgreen" }}
onClick={doneHandler}
className="cursor-pointer"
/> // ② Todo내용 완료 처리
</div>
</li>
))}
</ul>
);
};
export default TodoList;
① Todo내용 삭제
- 삭제(ClearIcon) 클릭시 props.onRemoveItem(현재선택된내용의ID) 통하여 Todo(부모) 컴포넌트의 removeTodoHandler 함수를 호출 하여 삭제 처리 한다.
② Todo내용 완료 처리
- 완료(DoneIcon) 클릭시 내부의 doneHanler 함수를 호출 하여서 현재 완료여부 값을 setTaskDone 함수를 통하여 변경 한다.
- taskDone 이 true 이면 입력내용에 취소선을 넣어서 완료 표시를 하기위한 css 속성을 설정 하고 그 반대인 경우는 취소선을 해제하는 css 속성을 설정한다.
Wrap up
- useState 를 통하여 값을 변경하는 경우 변경 함수를 통하여서 값을 변경한다.
- 부모-자식 간의 값 전달은 props를 통하여 할 수 있다. 물론 props 외에도 다른 방법이 있지만 본예제에서는 props를 통한 값의 전달 및 목록 갱신에 대해서 알아 보았다.
예제소스 및 프로젝트 생성 및 라이브러리 설치 방법
https://github.com/roopy1210/react-project-react-hook-usestate-example
'React > React Hook' 카테고리의 다른 글
useState 와 클로저 (0) | 2022.11.10 |
---|