App.js
import React, { useCallback, useRef, useState } from 'react';
import TodoInsert from './components/TodoInsert';
import TodoList from './components/TodoList';
import TodoTemplate from './components/TodoTemplate';
function App() {
const [todos, setTodos] = useState([
{
id: 1,
text: '리액트의 기초 알아보기',
checked: true,
},
{
id: 2,
text: '컴포넌트 스타일링 해보기',
checked: true,
},
{
id: 3,
text: '일정 관리 앱 만들기',
checked: false,
},
]);
const nextId = useRef(4);
const onInsert = useCallback(text => {
const todo = {
id: nextId.current,
text,
checked: false,
};
setTodos(todos.concat(todo));
nextId.current++;
}, [todos])
return (
<>
<TodoTemplate>
<TodoInsert onInsert={onInsert} />
<TodoList todos={todos} />
</TodoTemplate>
</>
);
}
export default App;
TodoInsert.js
import { useCallback, useState } from 'react';
import {MdAdd} from 'react-icons/md';
import './TodoInsert.scss';
function TodoInsert({onInsert}) {
const [value, setValue] = useState('');
const onChange = useCallback(e => {
setValue(e.target.value);
}, []);
const onSubmit = useCallback(e => {
e.preventDefault();
onInsert(value);
setValue('');
}, [value, onInsert]);
return (
<form className='TodoInsert' onSubmit={onSubmit}>
<input
placeholder='할 일을 입력하세요'
onChange={onChange}
value={value}
/>
<button type='submit'>
<MdAdd />
</button>
</form>
)
}
export default TodoInsert;
useRef와 useCallback
- nextId는 useState가 아닌 useRef로 관리
- nextId는 렌더링 되는 정보가 아님
- 예를 들어 화면에 보이지도 않고, 바뀐다고 해서 컴포넌트가 리렌더링 될 필요 없음(참조값)
- useRef 값은 .current 붙여주기
- onInsert 함수는 useCallback으로 감싸기
- props로 전달할 함수는 useCallback으로 감싸는 것을 습관 들이자