ํฐ์คํ ๋ฆฌ ๋ทฐ
์๋ฐ์คํฌ๋ฆฝํธ๋ก๋ ๊ทธ๋์ 2-3๋ฒ ์ ๋ ๋ง๋ค์ด๋ณธ ๊ฒ ๊ฐ์๋ฐ..๐ค
๋ฆฌ์กํธ๋ก๋ ๊ฐ์ ๋ฐ๋ผ ์น ๊ธฐ์ต๋ง ๋๊ณ ํผ์ ํ์ผ๋ก๋ ๋ง๋ค์ด๋ณธ ๊ธฐ์ต์ด ์๋ ๊ฒ ๊ฐ์๋ค.
์ด๋ ๊ฒ ๋๊ฑฐ ๊ฐ๋จํ ํฌ๋ ์ฑ์ ๋ง๋ค๋ฉด์ ๋ฆฌ์กํธ ๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋ค์ ์ก๊ณ ์ถ๋ค๋ ์๊ฐ์ด ๋ค์๋ค!
๐จ ๋์์ธ
๊ธฐ๋ฅ ๊ตฌํ์ด ๋ ์ค์ํ ๊ฒ ๊ฐ์์ ๋์์ธ์ ์ด์ด์ด ๊น๋ํ๊ฒโจ ํด์ผ์ง ์๊ฐํ๋ค.
ํผ๊ทธ๋ง๋ฅผ ์ ๋ค๋ฃจ์ง๋ ๋ชปํ์ง๋ง ์์ ๋ชจ๋ฅด๋ ๊ฑด ์๋๊ธฐ์ ํผ๊ทธ๋ง๋ฅผ ์ด์ฉํด ๋์์ธ ์์์ ์ก์๋ณด์๋ค.
(์ฌ๋ฐฑ์ ๋ฏธ-!ใ
ใ
ใ
)
โ๏ธ ๊ธฐ๋ฅ
๊ธฐ๋ฅ ๊ตฌํ์ ์์์ ์ปดํฌ๋ํธ๋ฅผ ๊ธฐ๋ฅ๋ณ๋ก ๋๋์ด ์ฃผ์๋ค.
๊ณตํต ์ปดํฌ๋ํธ (๋ฒํผ, input)๋ฅผ ๋ง๋ค๊น ์๊ฐํ๋๋ฐ ์ฌ๊ธฐ์์๋ ๊ทธ์ ๋๊น์ง ํ์ํ์ง ์์ ๊ฒ ๊ฐ๋ค๊ณ ํ๋จํ๋ค.
๋ฐ๋ณตํด์ ์ฌ์ฉํ ๋งํ๊ฒ ๋ฒํผ๋ง๊ณ ๋ ์๋๋ฏํ..?ใ
ใ
๊ทธ๋์ ๊ทธ๋ฅ ์์ ๊ฐ์ด ๊ธฐ๋ฅ๋ณ๋ก ๋๋์ด์ฃผ์๋ค. ์ฐ์ตํ๋๊ฑฐ๋๊น ๊ฐ๋ณ๊ฒํ์!
๋ฑ๋กํ๊ธฐ
๋ฑ๋ก ๊ธฐ๋ฅ์ ๋ฑ๋ก ๋ฒํผ์ ๋๋ ์ ๋ ํ ์ผ์ด ์ถ๊ฐ๋๋๋ก ๊ตฌํํ๋ค.
๐ ํ ์ผ ๋ฑ๋ก๊ณผ์
input์
onChange
์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ๋๋ง๋ค ๊ทธ ๊ฐ์setInputValue
ํจ์์ ๋ฃ์ด useState๋ก ๊ด๋ฆฌํ๋ค.const onChangeInput = (e) => { const { value } = e.target; setInputValue(value); };
๋ฑ๋ก ๋ฒํผ ํด๋ฆญ ์, ์ ๋ ฅํ ๊ฐ์ด ์๋ค๋ฉด
setTodoList
ํจ์์ ๋ค์๊ณผ ๊ฐ์ ๊ฐ์ฒดํํ์ todo๋ฅผ ๋ฃ์ด useState๋ก ์ํ๋ฅผ ๊ด๋ฆฌํด์ฃผ๋๋ก ํ๋ค.const [todoList, setTodoList] = useState([]); const [todoId, setTodoId] = useState(0); const onClickAddTodo = () => { if (inputValue) { setTodoList((prev) => [ ...prev, { id: todoId, text: inputValue, done: false, isUpdating: false, }, ]); setTodoId((prev) => prev + 1); setInputValue(""); } };
todoList ์ํ๊ฐ ์ ๋ฐ์ดํธ ๋ ๋๋ง๋ค ํด๋น ๊ฐ์ localStorage์ ์ ์ฅํด์ค๋ค.
useEffect(() => { localStorage.setItem("todoListData", JSON.stringify(todoList)); }, [todoList]);
์ต์ด ๋ ๋๋ง ์, ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅ๋ ํฌ๋๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์์ ์ถ๋ ฅํด์ค๋ค.
useEffect(() => { const localTodoList = localStorage.getItem("todoListData"); if (localTodoList) { setTodoList(JSON.parse(localTodoList)); } }, []);
์์ ํ๊ธฐ
๐ ํ ์ผ ์์ ๊ณผ์
์์ ๋ฒํผ ํด๋ฆญ ์ todo์ id์ ์์ ๋ฒํผ์ด ๋๋ฆฐ todo์ id๊ฐ ๊ฐ๋ค๋ฉด, todoList ๊ฐ์ฒด์์ isUpdating์ ture๋ก ๋ฐ๊พธ์ด์ค๋ค.
const onEdit = (id) => { setTodoList( todoList.map((todo) => todo.id === id ? { ...todo, isUpdating: !todo.isUpdating } : todo ) ); };
์์ ์ค์ธ ์ํ๊ฐ ๋๋ฉด todoItem์ด
span
์์input
์ผ๋ก ๋ณ๊ฒฝ๋๋ค.
์ด๋, input์ value๋ ์๋ ์ ๋ ฅ๋์๋ ๊ฐ์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๊ณ ์์ ์ ํตํด ๋ณ๊ฒฝ๋์ด์ผํ๊ธฐ ๋๋ฌธ์ useState๋ฅผ ํตํด ์ํ๋ฅผ ๊ด๋ฆฌํ๋๋ก ํ๋ค.
const [newText, setNewText] = useState(text);
{isUpdating ? (
<input
type="text"
onKeyDown={(e) => onEnterEdit(e, id)}
onChange={(e) => onChangeEditInput(e)}
value={newText}
className="updateTodoInput"
></input>
) : (
<span className={done ? "checked checkedText" : ""}>{text}</span>
)}
input์์
onChange
์ด๋ฒคํธ๊ฐ ์๊ธฐ๋ฉด ํด๋น ๊ฐ์setNewText
ํจ์๋ฅผ ํตํด ์๋ก์ด ๊ฐ์ ์ํ๋ก ์ ๋ฐ์ดํธ ์์ผ ๊ด๋ฆฌํ๋ค.const onChangeEditInput = (e) => { setNewText(e.target.value); };
์์ ํ ์ํฐ๋ฅผ ๋๋ฅด๋ฉด
onKeyDown
์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ณ ,setTodoList
ํจ์๋ฅผ ํตํด todoList ๊ฐ์ฒด์ text๊ฐ ์๋ก์ด ํ ์คํธ ๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ๋๊ณ ์์ ์ค์ธ ์ํ(isUpdating)๊ฐ false๋ก ๋ณ๊ฒฝ๋๋ค.const onEnterEdit = (e, id) => { if (e.key === "Enter") { setTodoList( todoList.map((todo) => { if (todo.id === id) { return { ...todo, text: newText, isUpdating: false }; } return todo; }) ); } };
5. ์ถ๊ฐ๋ก, ์์ ์ค์ผ ๋์๋ โ
๋๋ โ๏ธ ์์ด์ฝ์ด ๋จ์ง ์๋๋ก ํ๊ธฐ ์ํด ๋ค์์ ์ฝ๋๋ฅผ ์ถ๊ฐํ์๋ค.
- ์์ ์ค์ผ ๊ฒฝ์ฐ : ""
- ์์ ์ค์ด ์๋ ๊ฒฝ์ฐ
- ์๋ฃ ์ํ๋ผ๋ฉด : โ
- ์๋ฃ ์ํ๊ฐ ์๋๋ผ๋ฉด : โ๏ธ
```jsx
<span
className={done ? "checked" : ""}
onClick={() => checkToggle(id)}
>
{isUpdating ? "" : (done ? "โ
" : "โ๏ธ ")}
</span>
์ญ์ ํ๊ธฐ
ํ ์ผ ์ญ์ ๊ณผ์
ํ ์ผ์ ์๋ฃํ๋ฉด ์ฒดํฌ๋ฐ์ค๋ฅผ ํด๋ฆญํ๋ค.
todo์ id์ ์ฒดํฌ ๋ฒํผ์ด ๋๋ฆฐ todo์ id๊ฐ ๊ฐ๋ค๋ฉด, ํด๋น todoItem์ ๋ํด done ์ํ๋ฅผ true๋ก ๋ณ๊ฒฝ์ํจ๋ค.const checkToggle = (id) => { setTodoList( todoList.map((todo) => { if (todo.id === id) { return { ...todo, done: !done }; } return todo; }) ); };
ํ ์ผ์ด ์๋ฃ๋ ์ํ
(done: true)
์ด๊ฑฐ๋ ์์ ์ค์ด๋ผ๋ฉด ์์ ๋ฒํผ์ด ๋ํ๋์ง ์๋๋ก ํ๊ธฐ ์ํด ๋ค์์ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ค.{done || isUpdating ? ( <></> ) : ( <button onClick={() => onEdit(id)} className="todoitemBtn"> ์์ </button> )}
์ญ์ ๋ฒํผ ํด๋ฆญ ์, ์ญ์ ๋ฒํผ์ ๋๋ฅธ todoItem์ id๋ฅผ ์ ์ธํ todoList๋ฅผ
setTodoList
ํจ์๋ฅผ ํตํด ์ํ๋ฅผ ์ ๋ฐ์ดํธ ์์ผ์ค๋ค.const onRemove = (id) => { setTodoList(todoList.filter((todo) => todo.id !== id)); };
ํฌ๋ ์นด์ดํธ ์ธ๊ธฐ
์๋ฃ๋ ํ ์ผ(done: true)
๊ณผ ์์ง ์๋ฃ๋์ง ์์ ํ ์ผ(done: false)
์ ๋ํด ํํฐ๋ง์ ํ์ฌ ๊ทธ ๊ธธ์ด๋ฅผ ๋ณด์ฌ์ฃผ๋๋ก ํ๋ค.
const unDoneTodoList = todoList.filter((todo) => !todo.done);
const doneTodoList = todoList.filter((todo) => todo.done);
<span>โ๏ธ {unDoneTodoList.length}๊ฐ ๋จ์ </span>
<span>โ
{doneTodoList.length}๊ฐ ์๋ฃ</span>
๐ฟ ํธ๋ฌ๋ธ ์ํ
[์ค๋ฅ1] - useState ์ด๊ธฐํ๋ก ์ธํ ์ค๋ฅ
todo ๋ฑ๋ก ์์ useState๋ก ๊ด๋ฆฌ๋๋ id ๊ฐ์ ํจ๊ป ์ ์ฅํ๋๋ฐ ์ฌ๊ธฐ์ ์ค๋ฅ๊ฐ ์๊ฒผ๋ค.
const [todoList, setTodoList] = useState([]);
const [inputValue, setInputValue] = useState("");
const [todoId, setTodoId] = useState(0);
const onClickAddTodo = () => {
if (inputValue) {
setTodoList((prev) => [
...prev,
{
id: todoId,
text: inputValue,
done: false,
isUpdating: false,
},
]);
setTodoId((prev) => prev + 1);
setInputValue("");
}
};
์ต์ด ๋ ๋๋ง ํ todo๋ฅผ ๋ฑ๋กํ๋ฉด ์ ๋๋๋ฐ ์๋ก๊ณ ์นจ์ ํ๋ฒ ํด์ฃผ๋ฉด todo์ id ๊ฐ์ด 0์ผ๋ก ๋ค์ ์ด๊ธฐํ๊ฐ ๋๋ ๊ฒ์ด๋ค.
๋ด๊ฐ ์๊ฐํ ํด๊ฒฐ๋ฐฉ๋ฒ์ ์ด๋ ๋ค.
- todoList๋ฅผ ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๊ฑฐ๊ธฐ์ id๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ
- todoList์ ๊ธธ์ด๋ฅผ id ๊ฐ์ผ๋ก ์ฐ๊ธฐ
- id ๊ฐ๋ ๋ฐ๋ก ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๊ณ ๊ฐ์ ธ์์ ์ฌ์ฉํ๊ธฐ
- Date.now() ์ฌ์ฉํ๊ธฐ
1๋ก ํด๋ณผ๊น ๊ณ ๋ฏผ์ ํ๋ค๊ฐ...๐ค 3์ id๊ฐ์ ๋ก์ปฌ์คํ ๋ฆฌ์ง์ ๋ฃ์ด๋ ๋๋๊ฑด๊ฐ? ๋ผ๋ ์๊ฐ์ด ๋ค์๊ณ
2๋ ๊ฐ์ ์ค๋ฅ๊ฐ ์๊ธฐ๋ ๊ฒ ๊ฐ์์ 4๋ฒ์ผ๋ก ์ต์ข
๊ฒฐ์ ํ๊ฒ ๋์๋ค.
๊ทผ๋ฐ ๋ญ๊ฐ ์ฐ์ฐํ๊ฒ ํด๊ฒฐํ ๊ธฐ๋ถ์ด๋ผ ์ข ๋ ์์๋ด์ผ๊ฒ ๋ค๐ฅฒ
[์ค๋ฅ2] - input ์ ๋ ฅ ์ ๋ชจ๋ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง
input์ ํ ์ผ์ ์
๋ ฅํ ๋ ๋ชจ๋ ์๊ฐ๋ง๋ค ๋ ๋๋ง์ด ์ผ์ด๋๋ ๊ฒ์ ํ์ธํ๋ค.
input์ ๋ํ ์ต์ ํ...๐ค ๋๋ฐ์ด์ค? ์ด๊ฑด ์๋ ๊ฒ ๊ฐ๊ณ ..
๊ทธ๋ฌ๋ค ๋ฌธ๋ ๋ฆฌ์กํธ๋ฅผ ์ฒ์ ๋ฐฐ์ธ ๋ ๋ค์๋ ๊ฐ์์์๋ input ์
๋ ฅ ์ ๋ ๋๋ง์ด ์ผ์ด๋๋ ์์ ๋ฅผ ๋ณธ ๊ธฐ์ต์ด ๋ฌ๋ค!! ์ผ๋ฅธ ๊ทธ ๋น์ ๋ฐฐ์ด ๊ต์ฌ๋ฅผ ๋ค์ ์ฐพ์๋ณด์๋๋ฐ React.memo
๋ฅผ ์ฐ๋ฉด ๋๋ค๊ณ ํ๋ค.
React.memo
React.memo
๋ ๊ณ ์ฐจ ์ปดํฌ๋ํธ(Higher Order Component, HOC)๋ก ์ปดํฌ๋ํธ๊ฐ ๋์ผํ props๋ก ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ ๋๋งํ๋ฉด, React.memo๋ฅผ ํธ์ถํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ๋ชจ์ด์งํ๋๋ก ๋ํํ์ฌ ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์๋ค.
์ฆ, React๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ๋ ๋๋งํ์ง ์๊ณ ๋ง์ง๋ง์ผ๋ก ๋ ๋๋ง๋ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฌ์ฉํ๋ค.
์ ๋ง ๊ฐ๋จํ๊ฒ ์ปดํฌ๋ํธ๋ฅผ ๋ด๋ณด๋ผ ๋ React.memo
๋ก ๊ฐ์ธ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
{...์ฝ๋}
export default React.memo(CreateTodo);
๋ค๋ฅธ ์ปดํฌ๋ํธ๋ค๋ ๋ชจ๋ React.memo
๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
์ด๋ ๊ฒ ๋๋ฉด ๊ฐ ์ปดํฌ๋ํธ์ props ๋ฐ์ดํฐ๋ค์ด ๋ณ๊ฒฝ๋์ง ์๋๋ค๋ฉด ๊ธฐ์กด์ ๊ฐ์ ๊ทธ๋๋ก ์ถ๋ ฅํด์ค๋ค.
๊ฒฐ๊ณผ
(์ฒ์์ ๋ ๋๋ง ์ฝ์์ด ๋๋ฒ ์ฐํ๋ ๊ฒ์ strict ๋ชจ๋ ๋๋ฌธ์ด๋ค.)
์ฝ์์ฐฝ์ ๋ณด๋ฉด ์ ๋ ฅํ ๋ ๋ ๋๋ง์ด ์ผ์ด๋์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค!๐คฉ
๐ ์ฐธ๊ณ
๋ฆฌ์กํธ ๊ณต์๋ฌธ์ - React.memo
๋ฒจ๋กํผํธ์ ํจ๊ปํ๋ ๋ชจ๋ ๋ฆฌ์กํธ - 19. React.memo ๋ฅผ ์ฌ์ฉํ ์ปดํฌ๋ํธ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง
'Front-end ๐ฅ๐ค > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- ๊ฐค๋ฌ๋ฆฌ๋์ฐ๊ธฐ
- php
- ๋ธ๋ก์ฒด์ธ
- JavaScript
- ํ์ฅ์ค์ต
- ์ ์ฒ๊ธฐ ์ค๊ธฐ ์ ๋ฆฌ
- set ๊ฐ์ฒด
- C์ธ์ด
- ์ค๋งํธ์ปจํธ๋ํธ
- ํ๋ก๊ทธ๋๋จธ์ค
- ์ ์ฒ๊ธฐ ์ค๊ธฐ
- ์กธ์ ์ํ์ค๋น
- php ๋ฌ๋ ฅ๋ง๋ค๊ธฐ ์์ฉ
- ํํ์ด์ง ๋ง๋ค๊ธฐ
- MySQL
- ์กธ์ ์ํ
- css grid
- indexOf()
- ๋ ธ๋ง๋์ฝ๋
- ์ด๋๋ฆฌ์
- php๊ฒ์ํ๋ง๋ค๊ธฐ
- DAPP
- ์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ ์ค๊ธฐ
- ๋ฐฑ์ค
- HTML
- ์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ ์ค๊ธฐ ์ ๋ฆฌ
- ์ ๋ณด์ฒ๋ฆฌ๊ธฐ์ฌ
- ๋ฆฌ์กํธ
- CSS
- ํ์ฅ์ค์ต ๊ธฐ๋ก
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |