react hook
메모리 관리에도 유용하다
# react hook
## useContext
### 저삭컴포넌트들의 전역 상태 관리를 도와준다.
## useReducer
### 공식문서에 state의 대체 함수라고 나와있음
### 다수의 하위값을 복잡한 로직으로 만드는 경우
### 상태값을 여러가지 사용할 경우 stateqheksms
### Reducer를 사용하는것이 좋다.
### 이전 상태를 다룰경우에도 이점이 있음
## useCallBack
### 메모이제이션 기법을 사용해서 콜백을 반환해준다.
### 컴퓨터가 동일한 연산을 반복할떄 이전연산값을
### 메모리에 저장하고 반복수행을 줄이는것 (연산의 반복을 제거하는것)
### 최적화 시키기위해 사용하는 기법
### 실행속도가 빨라진다.
## useMemo
### 메모이제이션 기법을 사용하는데
### useCallback은 메모이제이션 콜백함수를 반환하고
### useMemo는 메모이제이션 값을 반환한다.
global
import React,{createContext,useContext, useState} from 'react'
// useContext react에서 제공해주는 내장 hook함수이다.
// 전역상태 관리를 도와주는 함수
// 리액트는 데이터의 흐름이 단방향 자식에게 props로 전달하기떄문에 불편하다.
// props로 데이터를 넘겨주지않아도 컴포넌트들이 데이터를 공유할수있도록 .
//
// 글로벌이라는 context객체 생성
export const Global = createContext()
const Context01=()=>{
return<>
<Context02></Context02>
</>
}
const Context02=()=>{
const {name,setname}= useContext(Global);
// Global.Provider value로 전달한 값을 받기위해
// useContext() 매개변수로 context객체를 전달해준다.
return<>
내이름은 {name}
<button onClick={()=>{setname("soon2")}}>버튼</button>
</>
}
const Context = () => {
//Context 최상단 부모 컴포넌트
const [name,setname]=useState("wook");
//부모의 상태변수
const obj= {
name,
setname
}
// 부모의 상태 변수 name과 상태변수 업데이트 함수 setName를 객체의 카값으로 obj객체에 선언
return (
// 안에 애들에게 값을 주입시킨다??
// 전역상태를 관리할때 Global.Provider를 최상단 트리로 감싸주고
// value는 정해진 키 전달할 데이터를 넣어준다.(전역상태)
<Global.Provider value={obj}>
{/* <div>Context</div> */}
<Context01></Context01>
</Global.Provider>
)
}
export default Context
reducer
import React, { useReducer } from 'react'
const INCREMENT = "INCREMENT"
const DECREMENT = "DECREMENT"
// 더하기 뺄셈만 간단하게 구현
// useState를 사용하것과 크게차이가없음
// react에서 제공해주는 내장 hook 함수
const Reducer = () => {
//상태 초기값
const init = {
count: 0,
}
//reducer 함수 매개변수로 상태와 액션을 넣어줄예정(콜백함수 왜?)
const reducer = (state, action) => {
// type 이라는 키값을 전달받을거임
// action객체에
// reducer 함수는 반환값이 있어야하니까 return
const { tpye,key } = action
switch (key) {
case INCREMENT:
//이전상태를 가지고 기능을 작성한뒤에 반환값으로 상태를 업데이트해주면된다. reducer는 useState의 대체함수이다.?
return {...state,count:state.count+1};
case DECREMENT:
return {...state,count:state.count-1};
default:
return state;
}
}
// 배열의 구조분해할당 첫번쨰 두번쨰를 매개변수로 받음
// useReducer 함수에 첫번쨰는 메뉴판 두번쨰는 초기값을 전달
const [state, dispatch] = useReducer(reducer, init);
return (
<div>지금 count의 상태는 : {state.count}
<button onClick={()=>{dispatch({type:INCREMENT})}}>더하기</button>
<button onClick={()=>{dispatch({type:DECREMENT})}}>뺴기</button>
</div>
)
}
export default Reducer
useCallback
import React, { useCallback, useState } from 'react'
// 공식문서에 useCallback은 메모이제이션 콜백을 반환한다는 내용이있음
// 메오이제이션하기위해서 사용하는 리액트 훅함수
const Callback = () => {
const [count,setcount]= useState(0);
const [count2,setcount2]=useState(0);
const handleCount = useCallback(()=>{
setcount(count+1);
// 복잡한 연산을 사용하는경우 근데 그연산이 동일한값으 내보내는 경우
// 메모이제이션 기법으로 동일한 연산일경에는 메모리에 가지고있다가
// 사용하는 기법 다른결과가 필요할경우에만 다시 메모이제이션 콜백을
// 반환해서 사용하는것.
},[count2]);
// 첫번쨰 매개변수는 콜백함수를 전달하고 두번쨰 매개변수는 배열을 전달한다.
// 이 배열에 들어가는 값이 주시하는 값
// count2 값이 변하기 전까지는 메모이션 콜백을 반환한다.
const handlerCount2=useCallback(()=>{
setcount2(count2 + 1);
},[count2])
return (
<div>
<div>
<h1>첫번째:{count}</h1>
<p>나는 count2가 변하지않으면 안변해 메모이제이션된 콜백이야.</p>
<button onClick={handleCount}>count</button>
</div>
<div>
<h1>두번째카운트:{count2}</h1>
<button onClick={handlerCount2}>count2</button>
</div>
</div>
)
}
export default Callback
useMemo
import React, { useMemo, useState } from 'react'
const Memo = () => {
const [count,setCount] = useState(0);
const [count2,setCount2]=useState(0);
const handleCount = ()=>{
console.log("나 count");
setCount2(count+1);
}
// 컴포넌트의 리렌더링을 관리하고싶음
// 부모컴포넌트가 리렌더링 되면 자식 컴포넌트가 리렌더링 되는데
// 부모컴포넌트 안에 자식 컴포넌트가 무척많으면 전부 리렌더링 되는데 그럼 페이지가
// 최적화지않는다.
// 그떄 사용하는게 useMomo
const handlerCount2=useMemo(()=>{
console.log("나 count2");
return (count+1)
},[count2])
// count2 를주시하고있다가 값이 변하면 새로운 값으로 업데이트
return (
<div>
<p>memo</p>
<button onClick={handleCount}>더하기</button>
{/* 화면을 다시그려주면서 함수 실행식이 계속실행되는데 그 반복을 막을수없을까해서 하는게 메오이제이션이고 usememo이다. */}
<p>handlecount2:{handlerCount2}</p>
</div>
)
}
export default Memo
// 컴포넌트:
// 할일리스트 부모 컴포넌트,
// 내용 컴포넌트들
// 전역으로 내용관리하자
// 작성컴포넌트 팝업
// 할일리스트 게시판 제목, 사용자 이름변경
// 제목 변경시 안의 내용은 렌더링 x
// 안의 내용이 렌더링되는건 할일리스트
// 부모컴포넌트안의 내용이 추가뒤었을때
// slack 사용하면 자동으로 git에서 업데이트시 볼수있음
// 컨트렉 개발시 event&log를 담는게 좋다. gas limit 이슈 wallet connect ?
usecontext, useMemo
import React, { useState ,useContext,useMemo} from 'react';
import Popup from './todo/Popup';
import Todolist from './todo/Todolist';
// import { Global } from './context/Context';
const Title = ({ maintitle }) => {
console.log('Rendering Title');
return <h1>{maintitle}</h1>;
};
const App = () => {
const [isPopupOpen, setIsPopupOpen] = useState(false);
// const {name,setname,task,settask,onClose,setcontent}= useContext(Global);
// const {name} = useContext(Global);
const [maintitle,setmaintitle] = useState("My App");
const handleOpenPopup = () => {
setIsPopupOpen(true);
};
const handleClosePopup = () => {
setIsPopupOpen(false);
};
const handleTitleChange=(e)=>{
setmaintitle(e.target.value)
}
const memoizedTitle = useMemo(() => <Title maintitle={maintitle} />, [maintitle]);
return (
<div>
<h1>{memoizedTitle}</h1>
<input onChange={handleTitleChange}></input>
{/* <Todolist> */}
<button onClick={handleOpenPopup}>Create Task</button>
{isPopupOpen && <Todolist onClose={handleClosePopup} />}
{/* </Todolist> */}
</div>
);
};
export default App;
import React, { useState,useContext, useMemo } from 'react';
import { Global } from './Todolist';
const Popup = () => {
// const [task, setTask] = useState('');
const {name,setname,task,settask,onClose,setcontent,content}= useContext(Global);
console.log(setcontent);
const handleInputChange = (e) => {
settask(e.target.value);
};
const handletitleChange=(e)=>{
setname(e.target.value);
}
const handleSave = () => {
let newcontent = {
name: name,
task: task
}
setcontent([...content, newcontent]);
};
const sdf = useMemo(()=>{
console.log("sd")
},[content])
return (
<div className="popup">
<div className="popup-content">
<h2>Create Task</h2>
<input
type="text"
value={name}
onChange={handletitleChange}
placeholder="Enter title"
/>
<input
type="text"
value={task}
onChange={handleInputChange}
placeholder="Enter task"
/>
<button onClick={handleSave}>Save</button>
<button onClick={onClose}>Cancel</button>
</div>
</div>
);
};
export default Popup;
import React, { createContext, useState, useMemo, useEffect } from 'react';
import Popup from './Popup';
export const Global = createContext();
const Todolist = ({ onClose }) => {
const [name, setname] = useState('정현욱');
const [task, settask] = useState('');
const [content, setcontent] = useState([]);
const obj = {
name,
setname,
task,
settask,
onClose,
content,
setcontent
}
// const obj = useMemo(
// () => ({
// name,
// setname,
// task,
// settask,
// onClose,
// content,
// setcontent
// }),
// [name, setname, task, settask, onClose, content, setcontent]
// );
useEffect(()=>{
console.log("dfdfddfdfdfdff", content)
}, [content])
const mappedContent = useMemo(
() =>
content.map((item, index) => (
<div key={index}>
{item.name}
{item.task}
{console.log("축하드립니다^^")}
</div>
))
,
[content]
);
return (
<div>
<Global.Provider value={obj}>
<Popup />
{mappedContent}
</Global.Provider>
</div>
);
};
export default Todolist;
const mappedContent = useMemo( () => content.map((item, index) => ( <div key={index}> {item.name} {item.task} {console.log("축하드립니다^^")} </div> )) , [content] );
return ( <div> <Global.Provider value={obj}> <Popup /> {mappedContent} </Global.Provider> </div> ); };
content 에변경사함이있을때 비교한뒤 렌더링할지 안할지 결정?
React의 'useMemo' 후크는 의존성 배열에 제공된 의존성을 비교하여 메모된 값을 다시 계산해야 하는지 또는 재사용해야 하는지 결정합니다. 그리고 그안에 콜백함수를 실행하는것
useMemo 후크에 의해 생성된 메모화된 값은 모든 유형의 JavaScript 값입니다 종속성의 값이 들어간다고 생각하면 좋을듯
gpt와 질의응답







'frontend > react' 카테고리의 다른 글
| 20230710 react 변수의 전역화 (1) | 2023.09.07 |
|---|---|
| 20230628~29 react시작 (1) | 2023.09.07 |