react강의 노트 | Byte Degree [4주차]
1. 커스텀 hook 만들어보기
useInputs
- useState, useCallback
import { useState, useCallback } from "react";
//커스텀 hook 만들어서 사용해보기
function UseInputs(inintialForm) {
const [form, setForm] = useState(inintialForm);
const onChange = useCallback((e) => {
const { name, value } = e.target;
setForm((form) => ({ ...form, [name]: value }));
}, []);
const reset = useCallback(() => setForm(inintialForm), [inintialForm]);
return [form, onChange, reset];
}
export default UseInputs;
useInputs
- useReducer, useCallback
import { useCallback, useReducer } from "react";
//useReducer 사용해보기
function reducer(state, action) {
switch (action.type) {
case "CHANGE_USER":
return {
...state,
[action.name]: action.value,
};
case "RESET_INPUT":
return Object.keys(state).reduce((acc, current) => {
acc[current] = "";
return acc;
}, {});
default:
return state;
}
}
function useInputs(inintialForm) {
const [form, dispatch] = useReducer(reducer, inintialForm);
const onChange = useCallback((e) => {
const { name, value } = e.target;
dispatch({
type: "CHANGE_USER",
name,
value,
});
}, []);
const reset = useCallback(() => {
dispatch({
type: "RESET_INPUT",
});
}, []);
return [form, onChange, reset];
}
export default UseInputs;
2. context API - useContext를 사용하여 전역 값 관리하기
- useList를 보면 useList 컴포넌트는 onChange props를 직접 사용하지 않고 App.js에서 user 컴포넌트로 전달해주는 역할만 한다. 이러한 코드를 개선하기 위해서 context API 사용으로 App.js에서 바로 User 컴포넌트로 넘어가게 하기.
//useContext 사용을 안한다면
import React, from "react";
function Child({ text }) {
return <div>안녕하세요 {text}</div>;
}
function Parent({ text }) {
return <Child text={text} />;
}
function Grandparent({ text }) {
return <Parent text={text} />;
}
function ContextSample() {
return <Grandparent text="good" />;
}
export default ContextSample;
//props를 계속 넘겨줘야한다
↓
//useContext hook 사용
import React, { createContext, useContext } from "react";
const MyContext = createContext("defaultValue");
function Child() {
const text = useContext(MyContext);
return <div>안녕하세요 {text}</div>;
}
function Parent() {
return <Child />;
}
function Grandparent() {
return <Parent />;
}
function ContextSample() {
return (
<MyContext.Provider value="good">
<Grandparent />;
</MyContext.Provider>
);
}
export default ContextSample;
- props의 넘김 없이 바로 받을 수 있다.
- reducer을 사용하지 않고 useState로 내부에서 모든걸 작업했다면 dispatch가 없기 때문에 useContext 사용이 조금 복잡.
3. Immer 라이브러리 사용으로 쉽게 불변성 지키기
- 설치 : npm install immer
const Object = {
a:1,
b:2
};
Object.b = 3; //기존 객체가 변함
//불변성 지키기
const Object = {
a:1,
b:2
};
const nextObject = {
...Object, //기존 객체 복사
b:3
};
댓글을 추가하는 코드를 작성한다면
const state = {
posts: [
{
id: 1,
title: '제목입니다.',
body: '내용입니다.',
comments: [
{
id: 1,
text: '와 정말 잘 읽었습니다.'
}
//이 밑으로 댓글을 추가하려면?
]
},
{
id: 2,
title: '제목입니다.',
body: '내용입니다.',
comments: [
{
id: 2,
text: '또 다른 댓글 어쩌고 저쩌고'
}
]
}
],
selectedId: 1
};
const nextState = {
...state, //기존 객체 가져오고
posts: state.posts.map(post => //객체중 id=1 post 찾기
post.id === 1 //id=1이면
? {
...post, //id=1인 post 가져오고
comments: post.comments.concat({
id: 3,
text: '새로운 댓글' //새롭게 작성된 post concat으로 연결
})
}
: post //id=1 아니면 기존 그냥 유지
)
};
----------------↓---------------------
//immer 사용시
const nextState = produce(state, draft => {
const post = draft.posts.find(post => post.id === 1);
post.comments.push({
id: 3,
text: '와 정말 쉽다!'
});
});
- immer 사용하면 불변성을 해치는 코드(ex) push)를 작성해도 대신 불변성 유지를 해준다.
- immer사용해보기
const state = {
number: 1,
dontChangeMe: 2
};
const nextState = produce(state, draft => {
draft.number += 1;
});
console.log(nextState);
// { number: 2, dontChangeMe: 2 }
- produce(바꿔줄 객체or배열, 어떻게 바꿀지 함수(draft로 받아옴))
- push도 가능
완전 좋은 라이브러리다....
- reducer immer로 구현하기
case "TOGGEL_USER":
return {
...state,
users: state.users.map((user) =>
user.id === action.id ? { ...user, active: !user.active } : user
),
};
//immer사용, TOGGEL_USER
case "TOGGEL_USER":
return produce(state, (draft) => {
const user = draft.users.find((user) => user.id === action.id);
user.active = !user.active;
});
- 데이터 구조가 복잡하거나 필요한 곳에서만 사용하는 것이 좋다.
- 간단하게 구현할 수 있는 것은 immer사용보다 native reducer사용하기
'React' 카테고리의 다른 글
API 연동하기 (useState, useEffect, useReducer) (0) | 2020.12.24 |
---|---|
[React 강의 노트(5)] class형 component (0) | 2020.12.16 |
[React 강의 노트(3)] Hook - useEffect, useMemo, userCallback, useReducer (0) | 2020.12.13 |
[React 강의 노트(2)] CRUD (0) | 2020.12.10 |
[React 강의 노트(1)] React (0) | 2020.12.09 |