※ 강의를 듣고 제가 이해한 내용을 바탕으로 정리한 것이라서 오류가 있을 수 있습니다.

 

할 일 목록 구현하기

 

1. 프리젠테이셔널 컴포넌트 구현하기

먼저 Todos 라는 프리젠테이셔널 컴포넌트를 구현하겠다.

components 디렉터리에 Todos.js 파일을 생성한다.

이 파일에는 TodoItem, TodoList, Todos 이렇게 총 3가지의 컴포넌트를 작성 할 것이다. 이렇게 여러개의 컴포넌트를 만드는 이유는 컴포넌트의 리렌더링 성능을 최적화하기 위함이다. 지금은 편의상 한 파일에 모두 작성을 할건데 취향에 따라 각각 다른 파일에 분리하셔도 상관 없다.

components/Todos.js

import React, { useState } from 'react';
// 컴포넌트 최적화를 위하여 React.memo를 사용한다
const TodoItem = React.memo(function TodoItem({ todo, onToggle }) {
return (
<li
style={{ textDecoration: todo.done ? 'line-through' : 'none' }}
onClick={() => onToggle(todo.id)}
>
{todo.text}
</li>
);
});
// 컴포넌트 최적화를 위하여 React.memo를 사용한다
const TodoList = React.memo(function TodoList({ todos, onToggle }) {
return (
<ul>
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} onToggle={onToggle} />
))}
</ul>
);
});
function Todos({ todos, onCreate, onToggle }) {
// 리덕스를 사용한다고 해서 모든 상태를 리덕스에서 관리해야하는 것은 아니다.
const [text, setText] = useState('');
const onChange = e => setText(e.target.value);
const onSubmit = e => {
e.preventDefault(); // Submit 이벤트 발생했을 때 새로고침 방지
onCreate(text);
setText(''); // 인풋 초기화
};
return (
<div>
<form onSubmit={onSubmit}>
<input
value={text}
placeholder="할 일을 입력하세요.."
onChange={onChange}
/>
<button type="submit">등록</button>
</form>
<TodoList todos={todos} onToggle={onToggle} />
</div>
);
}
export default Todos;

 

2. 컨테이너 컴포넌트 만들기

이제 컨테이너 컴포넌트도 만든다.

containers 디렉터리에 TodosContainer.js 파일을 생성해서 다음과 같이 작성한다.

 

containers/TodosContainer.js

import React, { useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Todos from '../components/Todos';
import { addTodo, toggleTodo } from '../modules/todos';
function TodosContainer() {
// useSelector 에서 꼭 객체를 반환 할 필요는 없다.
// 한 종류의 값만 조회하고 싶으면 그냥 원하는 값만 바로 반환하면 된다.
const todos = useSelector(state => state.todos);
const dispatch = useDispatch();
const onCreate = text => dispatch(addTodo(text));
const onToggle = useCallback(id => dispatch(toggleTodo(id)), [dispatch]); // 최적화를 위해 useCallback 사용
return <Todos todos={todos} onCreate={onCreate} onToggle={onToggle} />;
}
export default TodosContainer;

 

App.js

import React from 'react';
import CounterContainer from './containers/CounterContainer';
import TodosContainer from './containers/TodosContainer';
function App() {
return (
<div>
<CounterContainer />
<hr />
<TodosContainer />
</div>
);
}
export default App;

 

실행 결과

+ Recent posts