리덕스 사용해서 수정하기 기능 구현하기
수정한 코드
components/Todos.js
import React, { useState } from "react";
// 컴포넌트 최적화를 위해 React.memo 사용
const TodoItem = React.memo(function TodoItem({ todo, onToggle, onEdit }){
return (
<li
// style={{ textDecoration: todo.done ? 'line-through' : 'none'}}
// onClick={()=> onToggle(todo.id)}
onClick={() => onEdit(todo.id, todo.text)} // 클릭시 onEdit 이벤트 발생. id와 text 파라미터로 보냄
>{todo.text}</li>
);
});
// 컴포넌트 최적화를 위해 React.memo 사용
const TodoList = React.memo(function TodoList({todos, onToggle, onEdit}){
return (
<ul>
{todos.map(todo=> (
<TodoItem key={todo.id} todo={todo} onToggle={onToggle} onEdit={onEdit}/>
))}
</ul>
);
});
function Todos({todos, onCreate, onToggle, onUpdate}) {
// 리덕스를 사용한다고 해서 모든 상태를 리덕스에서 관리해아하는 것은 아니다
const [text, setText] = useState('');
const [editYN, setEditYN] = useState(false); // 수정모드 전환용 state
const [targetId, setTargetId] = useState(0); // 선택된 요소의 id를 기억할 state
const onChange = e => setText(e.target.value);
const onSubmit = e => {
e.preventDefault(); // submit 이벤트 발생시 새로고침 방지
onCreate(text);
setText(''); // 인풋 초기화
}
const onEdit = (id, text) => {
setText(text); // input의 value를 todo.text로 변경
setTargetId(id); // targetId를 클릭된 요소의 id로 변경
setEditYN(true); // 수정모드 true
}
const onReset = () => {
setText('');
setTargetId(0);
setEditYN(false);
};
return (
<div>
<form>
<input
value={text}
placeholder="할일을 입력해주세요"
onChange={onChange} />
{ editYN ?
<button type="button" onClick={() => {
onUpdate(targetId, text) // 내용수정 이벤트
onReset() // 수정후 초기화 이벤트
}}>수정</button>
:
<button type="button" onClick={onSubmit}>등록</button>
}
</form>
<TodoList todos={todos} onToggle={onToggle} onEdit={onEdit} />
</div>
);
}
export default Todos;
+) ????? 질문
return (
<div>
<form onSubmit={onSubmit}>
<input
value={text}
placeholder="할일을 입력해주세요"
onChange={onChange} />
{ editYN ?
<button type="button" onClick={() => {
onUpdate(targetId, text)
onReset()
}}>수정</button>
:
<button type="submit">등록</button>
}
</form>
<TodoList todos={todos} onToggle={onToggle} onEdit={onEdit} />
</div>
);
위의 코드일때는 초기화가 된 후 빈 할일이 하나씩 추가됨… 왜지
submit이 발생하면 빈 할일이 추가되는듯??
modules/todos.js
// 액션 타입 선언
const ADD_TODO = 'todos/ADD_TODO';
const TOGGLE_TODO = 'todos/TOGGLE_TODO';
const UPDATE_TODO = 'todos/UPDATE_TODO';
// 액션 생성함수 선언
let nextId = 1; // todo 데이터에서 사용할 고유 id
export const addTodo = text => ({
type: ADD_TODO,
todo: {
id: nextId++, // 새 항목 추가 후 nextId 값에 1을 더함
text
}
});
export const toggleTodo = id => ({
type: TOGGLE_TODO,
id
});
// 수정 버튼이 눌러졌을때 발생할 액션
export const updateTodo = (targetId, text) => ({
type: UPDATE_TODO,
targetId,
text
});
// 초기상태 선언
// 리듀서의 초기상태는 반드시 객체타입 X . 배열 O 원시타입(숫자, 문자, 불리언) O
const initialState = [
// 객체안에 들어갈 배열
/*
{
id: 1,
text: 'test',
done: false
}
*/
];
export default function todos(state = initialState, action) {
switch (action.type) {
case ADD_TODO :
return state.concat(action.todo);
case TOGGLE_TODO :
return state.map(
todo =>
todo.id === action.id // id가 일치하면
? {...todo, done: !todo.done} // done 값을 반전
: todo // 아니라면 그대로
);
case UPDATE_TODO :
return state.map(
todo =>
todo.id === action.targetId // id가 일치하면
? {...todo, text: action.text} // text 값을 변경하기
: todo // 아니라면 그대로
)
default:
return state;
}
};