리덕스로 투두리스트를 만들어보자!!
프리젠테이셔널 컴포넌트 구현
먼저, Todos라는 프리젠테이셔널 컴포넌트를 구현해보자. components 디렉터리에 Todos.js 파일을 생성한다.
Todos에는 TodoItem, TodoList, Todos 컴포넌트를 작성한다.
👉 컴포넌트를 여러개로 분리하면 컴포넌트의 리렌더링 성능을 최적화할 수 있다.
components/Todos.js
먼저, 다음과 같이 import 문을 작성한다.
import React, { useState } from 'react';
1. TodoItem 컴포넌트
할 일 목록 하나를 렌더링하는 컴포넌트
할 일을 완수했다면 텍스트 가운데에 줄이 그어지고 해당 컴포넌트를 클릭했을 경우에 onToggle 함수가 호출된다.
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
👉 컴포넌트의 props가 변경됐을 경우에만 리렌더링 되도록 해 컴포넌트의 리렌더링 성능을 최적화 시켜주는 함수
⚙️ textDecoration 속성
👉 선으로 텍스트를 꾸밀 수 있게 해주는 속성
- 문법 종류
1. none: 선을 만들지 않는다.
2. line-through: 글자 중간에 선을 만든다.
3. overline: 글자 위에 선을 만든다.
4. underline: 글자 아래에 선을 만든다.
5. initial: 기본값으로 설정한다.
6. inherit: 부모 요소의 속성값을 상속받는다.
- 속성값을 여러개 사용하는 방법
textDecoration: overline underline;
2. TodoList 컴포넌트
TodoItem 컴포넌트를 매핑해서 화면에 렌더링하는 컴포넌트
const TodoList = React.memo(function TodoList({ todos, onToggle }) {
return (
<ul>
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} onToggle={onToggle} />
))}
</ul>
);
});
3. Todos 컴포넌트
할 일 목록 form을 구현하는 컴포넌트
function Todos({ todos, onCreate, onToggle }) {
const [text, setText] = useState('');
const onChange = e => setText(e.target.value);
const onSubmit = e => {
e.preventDefault();
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>
);
}
⚙️ e.preventDefault()
👉 현재 이벤트의 기본 동작을 중지하는 함수
submit 이벤트가 발생했을 때 새로고침되는 것을 막기 위해 해당 함수 호출
컨테이너 컴포넌트 구현
컨테이너 컴포넌트도 만들어보자. 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() {
const todos = useSelector(state => state.todos);
const dispatch = useDispatch();
const onCreate = text => dispatch(addTodo(text));
const onToggle = useCallback(id => dispatch(toggleTodo(id)), [dispatch]);
return <Todos todos={todos} onCreate={onCreate} onToggle={onToggle} />;
}
export default TodosContainer;
APP 컴포넌트에서 렌더링
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;
결과 화면

참고
벨로퍼트와 함께하는 모던 리액트 https://react.vlpt.us/redux/07-implement-todos.html
'Redux' 카테고리의 다른 글
[Redux] 7. 리덕스 useSelector 최적화 (0) | 2021.06.30 |
---|---|
[Redux] 5. 리덕스 개발자도구 적용하는 방법 (0) | 2021.06.29 |
[Redux] 4. 리덕스로 카운터 구현하기 (0) | 2021.06.29 |
[Redux] 3. 리덕스 모듈 만들기 (0) | 2021.06.29 |
[Redux] 2. 리덕스 설치 및 예제 실행 (0) | 2021.06.28 |