=> useState, useEffect, useRef
- Hook은 React 16.8에 새로 추가된 기능으로 Hook은 class를 작성하지 않고도 state와 다른 React의 기능들을 사용할 수 있게 해줌
- 함수형 컴포넌트에서 상태를 관리 하는데 사용 되며 컴포넌트로 상태 값을 추가하고 값을 변경 할 수 있음.
- useState는 배열을 반환하며, 첫번째 요소는 상태 값, 두번째 요소는 상태 값을 업데이트 하는 함수.
const [data, setData] = useState(initialData);
useEffect는 컴포넌트 렌더링 이후 특정 작업을 수행할수 있게 해주는 훅.
- 호출 가능 상태
- 컴포넌트가 마운트 될 때(처음 화면에 나타날 때, 처음 화면에 렌더링 될 때)
- 컴포넌트가 업데이트 될 때(컴포넌트의 상태(state)나 속성(props)이 변경되어 컴포넌트가 다시 렌더링될 때)
- 컴포넌트가 언마운트 될 때(사용자가 페이지를 떠나거나 다른 페이지로 이동하여 해당 컴포넌트가 더 이상 필요하지 않을 때)
여기서는 렌더링이 될 때마다 data라는 state에 data를 넣고 있는 형태이다.
const [data, setData] = useState();
useEffect(() => {
setData(data)
});
/*
useEffect(() => {
setData(data)
},[]);
*/ // 이런식으로도 표현 가능
하지만 컴포넌트가 업데이트 될 때 useEffect를 사용하고 싶다면 밑에 코드 처럼 id라는 값이 변경 될 때마다 리렌더링 되어 useEffect 내부에 있는 변수들의 상태를 업데이트 하는 것에 사용될 수 있다.
useEffect(() => { const post = Data.find((post) => post.id === parseInt(id)); if (post) { setPost(post); } }, [id]);
앞선 useState, useEffect가 렌더링을 통해서 값의 변경이 이루어지는 것과 다르게 useRef는 다음과 같은 상황에서 사용되어 진다.
1. 값을 변경해도 컴포넌트가 리렌더링 되지 않고 캔버스나 비디오 요소와 같이, DOM 요소에 직접 접근하고 이를 조작해야 할 때 사용 되어 진다.
2. 상태(useState)와 달리, 값이 변경되어도 컴포넌트를 다시 렌더링하지 않기를 원할 때 사용된다. 즉 이전 렌더링 사이의 값이나 컴포넌트의 상태를 기억해야 할 때.
3. 입력 필드에 포커스를 설정하거나, 포커스를 이동시키는 등의 작업을 할 때 사용.
const headerCanvasRef = useRef(null); // header 캔버스에 대한 참조
const bodyCanvasRef = useRef(null); // body 캔버스에 대한 참조
- useRef로 생성한 bodyCanvasRef, headerCanvasRef에서 현재 참조하고 있는 DOM 요소를 가져오며 bodyCanvasRef.current, headerCanvasRef.current는 바디 캔버스 DOM 요소를 가리키며, 이를 bodyCanvas, headerCanvas 변수에 저장한다.
const headerCanvas = headerCanvasRef.current;
const bodyCanvas = bodyCanvasRef.current;
const headerCtx = headerCanvas.getContext("2d");
const bodyCtx = bodyCanvas.getContext("2d");
// Set canvas dimensions (전체 캔버스 크기 설정)
headerCanvas.width = 1300; // header 캔버스 너비 설정
headerCanvas.height = 50; // header 캔버스 높이 설정
bodyCanvas.width = 1300; // body 캔버스 너비 설정
bodyCanvas.height = 1200; // body 캔버스 높이 설정
- 이렇게 선언된 headerCanvasRef, bodyCanvasRef는 JSX 내에서 사용되며, 실제 DOM 요소가 이 참조에 연결된다.
<div>
<div style={{ paddingLeft: "100px", paddingTop: "90px", position: "sticky", top: "0", zIndex: "100" }}>
<canvas ref={headerCanvasRef} />
</div>
<div style={{ height: "1000px" }}>
<canvas ref={bodyCanvasRef} style={{ marginTop: "-54.5px", marginLeft: "100px", border: "1px solid #ddd" }} />
</div>
</div>
useEffect
- 사이드 이펙트를 처리해야 할 때, 즉 데이터 가져오기, 구독 설정, DOM 직접 조작, 타이머 설정 등의 작업을 처리해야 할 때 사용
- 컴포넌트가 렌더링될 때마다 또는 특정 상태/props가 변경될 때마다 작업을 수행해야 할 때: 종속성 배열을 통해 특정 상태나 props가 변경될 때마다 특정 작업을 수행
useState
- 컴포넌트의 상태를 관리해야 할 때, 즉 사용자의 입력, API 응답 데이터, UI의 상태(예: 모달 열림/닫힘 상태) 등 컴포넌트의 상태를 관리할 때 사용
- 상태가 변경될 때마다 컴포넌트가 다시 렌더링되어야 할 때, 즉 상태가 변경될 때마다 컴포넌트를 다시 렌더링하여 UI를 업데이트해야 할 때 사용
useRef
- DOM 요소에 직접 접근하거나, 렌더링 사이에 값을 유지해야 하며, 값의 변경이 컴포넌트를 다시 렌더링하지 않아야 할 때 사용
- 컴포넌트에 원하는 값 을 넘겨줄 때 사용하며 변수,함수,객체,배열 등 자바스크립트의 요소라면 제한이 없다.
- 컴포넌트의 재사용을 위하여 사용하며 읽기 전용으로 값 변경 불가
- 값을 변경하고 싶으면 새로운 변수를 생성해서 사용해야함
1. props를 활용하여서 props.지정이름 통해 사용가능 하다.
export const Eachseperateboard = styled(Link)`
border-left: 1px solid gray;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
width: ${(props) => props.width||"100%"};
height: 50px;
color: black;
font-size: 20px;
text-decoration: none;
&:hover{
background-color: gray;
}
`;
<Eachseperateboard width={"80%"} to={`/freeboard/${post.id}`}>{post.title}</Eachseperateboard>
2. 객체 props 받고 연산하기 및 함수도 props형태로 넘겨서 사용가능
//Schedule.js
const handleAdd = (newEntry) => {
setData([...data, newEntry]);
setaddEntry(!addEntry);
};
const handleCancel = () => {
setEditingEntry(null);
};
<AddModal onAdd={handleAdd} data={data} onCancel={handleaddCancel} />
//Scheduleadd.js
const AddModal = ({ onAdd, data, onCancel }) => {
const isConflict = data.some((entry) => {
return (
entry.day === day &&
((entry.startTime >= startTime && entry.startTime < endTime) ||
(entry.endTime > startTime && entry.endTime <= endTime) ||
(entry.startTime <= startTime && entry.endTime >= endTime))
);
});
// 넘겨 받은 data 객체를 .을 통해 객체 안의 값에 접근
const newEntry = {
id: data.length + 1,
subject,
professor,
day,
startTime,
endTime,
location,
color: getRandomColor(),
};
onAdd(newEntry);
// onAdd로 넘겨 받은 함수의 argument로 newEntry가 들어가는 형태 -> newEntry를 객체의 새로운 값으로 추가
return(<>
....
<button type="button" onClick={onCancel}
// onClick시에 props로 넘겨 받은 onCancel함수 실행
>
취소
</button>
</>
}
- 웹 브라우저가 알려주는 html 요소에 대한 사건을 의미 하며 유저 행동이나 개발자가 의도한 로직에 의해 발생한다.
- 이벤트 핸들러 함수: 이벤트를 처리하는 함수로서, 로직 처리 후 결과를 사용자에게 알린다.
- onClick: 해당 element 클릭 시에 발생하는 이벤트
<TfiWrite
onClick={() => handleEdit(hoveredEntry.id)}
//hover된 부분을 배열의 id로 찾아서 editEntry 값으로 지정한 뒤에
// 이를 바탕으로 수정할 시간표를 지정
>
// 해당 element 클릭 시에 handleEdit 함수가 hoveredEntry.id를 argument로 받고 실행된다.
```
>- onChange: text타입의 element에 입력된 값을 실시간으로 업데이트 하여 유연한 UI제공
``` javascript
<input
type="text"
value={subject}
onChange={(e) => setSubject(e.target.value)}
required
/>
// 입력될 때 마다 subject state가 setSubject를 통해 실시간 업데이트
- onSubmit: form 형태로 입력된 값들을 제출 할 시에
<form onSubmit={handleSubmit}>
<label>
과목명 (필수):
<input
type="text"
value={subject}
onChange={(e) => setSubject(e.target.value)}
required
/>
</label>
<label>
교수명:
<input
type="text"
value={professor}
onChange={(e) => setProfessor(e.target.value)}
/>
</label>
// onSubmit을 통해 button 클릭 시에 handleSubmit 함수 실행
// 엔터를 눌러도 onSubmit이 실행되며 주로 form 제출전 데이터 검증 및 form 데이터 처리 시에 onSubmit 사용
<button type="submit">저장</button>
</form>
onKeyDown,onKeyUp, onKeyPress: 키보드 입력 발생 시
onMouseLeave,onMouseEnter: 마우스 커서가 위에 있을 시 아닐시
<Adddiv
onClick={() => {
setaddEntry(!addEntry);
}}
onMouseEnter={() => setIsAdddivHovered(true)}
// Mouse가 위에 있을때 adddiv가 hover되었음을 나타냄
onMouseLeave={() => setIsAdddivHovered(false)}
// Mouse가 위에 없을 때 adddiv가 hover되지 않았음을 나타냄
>
```
참조: https://medium.com/@pdx.lucasm/canvas-with-react-js-32e133c05258
참조:https://madnix.tistory.com/entry/%EC%95%84%EA%B7%9C%EB%A8%BC%ED%8A%B8argument-%EC%99%80-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0parameter-%EC%9D%98-%EC%B0%A8%EC%9D%B4
참조: https://velog.io/@jellyjw/React-Hook-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
참조: https://velog.io/@ko9612/JavaScript-DOM
참조: https://velog.io/@lilys2/React-PropsStateEventHook-%EC%A0%95%EB%A6%AC
참조: https://enfanthoon.tistory.com/133