const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
메모이제이션된 콜백함수를 반환한다.의존성 배열의 값이 변경될때 에만 변경된 메모이션된 콜백함수를 반환한다.
기존코드
1.data가 [] 배열인 상태로 첫번째 렌더링 , props 전달 및 자식 컴퍼넌트 렌더링
2.setData로인해 data바뀌고 렌더링 ,props 전달 및 자식 컴퍼넌트 렌더링
최적화코드
1.data가 [] 배열인 상태로 첫번째 렌더링 ,props 전달 및 자식 컴퍼넌트 렌더링
2.setData로 인해 data바뀜 ,useCallback으로 props 전달 x, React.memo로 인해 자식 컴퍼넌트 렌더링 x
중요 usecallback을 사용하지 않으면 props를 부모컴퍼넌트에서 렌더링 할 때 props를 2번 전달해 2번 렌더링 된다.
function App() {
const dataId = useRef(0);
const [data,setData] = useState<Info[]>([]);
const getData = async () =>{
const res:tmp[] = await fetch(`https://jsonplaceholder.typicode.com/comments`).then((res)=>res.json());
const initData:Info[] = res.slice(0,20).map((it)=>{
return {
id:it.postId,
autor:it.email,
content:it.body,
emotion:Math.floor(Math.random() * 5)+1,
createDate: new Date().getTime(),
}
});
setData(initData);
};
useEffect(()=>{
getData();
},[]);
const onCreate:oncreate = useCallback((autor:string,content:string,emotion:number)=>{
const createDate = new Date().getTime();
const newItem = {
autor,
content,
emotion,
createDate,
id:dataId.current,
};
dataId.current+=1;
setData((prev)=>[newItem,...prev]);
},[]);
return (
<div className="App">
<DiaryEditor onCreate={onCreate}/>
<div>전체 일기 :{data.length}</div>
<div>기분 좋은 일기 개수:{goodCount}</div>
<div>기분이 나쁜 일기 개수:{badCount}</div>
<div>기분이 좋은 일기 비율:{goodRatio}%</div>
<DiaryList onDelete={onDelete} onEdit={onEdit} setList={data} />
</div>
);
}
export default App;
const DiaryEditor = ({onCreate}:{onCreate:oncreate}) => {
useEffect(()=>console.log("Diaryeditor렌더"));
const autorInput = useRef<HTMLInputElement>(null);
const textInput= useRef<HTMLTextAreaElement>(null);
const [state, setState] = useState(
{
autor:"",
content:"",
emotion:1
}
);
const handleChange = (e:ChangeEvent<HTMLInputElement | HTMLTextAreaElement| HTMLSelectElement>)=>{
setState({...state,[e.target.name]:e.target.value});
}
return(
<div className="DiaryEditor">
<h2>오늘의 일기</h2>
<input
ref={autorInput}
name="autor"
placeholder="작성자"
value={state.autor}
onChange={(e)=>{
let tmp = {...state};
tmp.autor = e.target.value;
setState(tmp);
}}
/>
<div>
<textarea
ref={textInput}
name="content"
placeholder="내용"
value={state.content}
onChange={handleChange}/>
</div>
<div>
<span style={{fontSize:12}}>오늘의 감정 점수 :</span>
<select
name="emotion" value={state.emotion} onChange={handleChange}>
<option value={1}>1</option>
<option value={2}>2</option>
<option value={3}>3</option>
<option value={4}>4</option>
<option value={5}>5</option>
</select>
</div>
<button onClick={()=>handleSubmit()}>일기 저장하기</button>
</div>
)
};
export default React.memo(DiaryEditor);