왜 useRef가 필요하고 변수는 변경할 수 없는가?
나는 효과 사용법을 위한 완벽한 가이드 - Swiming Against the Tread at Inspected를 읽었다.
에서는, 의 「」를 가 있는 에 대해 합니다.count
, 을할 수 있습니다.useRef
래스터로 .
function Example() {
const [count, setCount] = useState(0);
const latestCount = useRef(count);
useEffect(() => {
// Set the mutable latest value
latestCount.current = count;
setTimeout(() => {
// Read the mutable latest value
console.log(`You clicked ${latestCount.current} times`);
}, 3000);
});
// ...
}
단, 컴포넌트 함수 외부에 다음과 같은 변수를 생성함으로써 동일한 작업을 수행할 수 있습니다.
import React, { useState, useEffect, useRef } from 'react';
// defined a variable outside function component
let countCache = 0;
function Counter() {
const [count, setCount] = useState(0);
countCache = count; // set default value
useEffect(() => {
setTimeout(() => {
// We can get the latest count here
console.log(`You clicked ${countCache} times (countCache)`);
}, 3000);
});
// ...
}
export default Counter;
두 가지 방법 모두 실용적입니까, 아니면 가변 외부 기능 구성 요소를 정의하면 나쁜 점이 있습니까?
useRef
는 각 컴포넌트에 참조를 할당하지만 함수 컴포넌트 범위 외부에 정의된 변수는 한 번만 할당됩니다.
useRef
기준 수명은 구성 요소의 수명입니다(구성 요소가 마운트 해제되면 "디지스"하지만 JS 변수는 범위가 차단됨).
따라서 컴포넌트 범위 밖에서 상수 목적 변수를 정의합니다.
// This statement will only called once
const DEFAULT_VALUE = 5;
function Component() {
// use DEFAULT_VALUE.
}
컴포넌트 범위 내에서 동일한 문을 정의하면 모든 렌더에서 해당 문이 다시 정의됩니다.
// We can do better
function Component() {
// Redefined on every render
const DEFAULT_VALUE = 5;
}
다음 질문입니다.
첫째, 외부 범위 변수를 변경하면 렌더링이 트리거되지 않기 때문에 외부 범위 변수를 사용하여 변경된 UI를 실제로 반영할 수 없습니다(React API만 해당).
따라서 반사된 값이 닫힘 값입니다.
let countCache = 0;
function Counter() {
...
countCache = 0;
useEffect(() => {
countCache = count;
});
...
// closure value of countCache
return <div>{countCache}</div>
}
외부 스코프 변수는 모듈 자체에 대해 글로벌하기 때문에 그 값을 사용하는 것은 모듈 내의 모든 컴포넌트에 대해 글로벌하다는 점에서 특별한 점은 무엇입니까?
를 들어 .
useEffect
(하다
let howMuchMounted = 0;
function Component() {
useEffect(() => { howMuchMounted += 1, [] };
}
와 외부 변수의 합니다.useRef
예에서는 했을 때, 「 」, 「 」, 「 」, 「 」, 「 」가되는 경우가 있습니다.variable
컴포넌트에 대해 단, 「」는 「글로벌」입니다.reference
는 항상 현재 상태 값으로 갱신됩니다.
import React, { useEffect, useRef, useReducer } from "react";
import ReactDOM from "react-dom";
// defined a variable outside function component
let countCache = 0;
function Counter() {
const [num, count] = useReducer((num) => num + 1, 0);
const countRef = useRef(count);
useEffect(() => {
// set count value on count change
countCache = num;
countRef.current = num;
}, [num]);
return (
<>
<button onClick={count}>Count</button>
<h3>state {num}</h3>
<h3>variable {countCache}</h3>
<h3>reference {countRef.current}</h3>
</>
);
}
export default function App() {
return (
<>
<Counter />
<hr />
See what happens when you click on the other counter
<hr />
<Counter />
</>
);
}
사용 사례에 대한 후속 질문을 참조하십시오. 작업 시 자주 실수하는 경우가 많습니다.useRef
useEffect
.
다음 4가지 종류에는 차이가 있습니다.
- 함수 구성요소 내부의 변수
- 함수 성분 외부에 있는 변수
- useState()에 의해 반환된 상태 변수
- useRef()에 의해 반환된 변수(속성이 'current'인 개체)
마지막 2개는 컴포넌트 내에서만 사용할 수 있습니다.
각 사례를 살펴보겠습니다.
1. 함수성분 내부의 변수
Initialization
: 변수는 항상 모든 렌더링과 여러 컴포넌트 인스턴스에서 모두 다시 초기화됩니다.
Variable Updates
: const 이외의 갱신 가능
Render
: React에 의해 트리거된 렌더가 없으므로 업데이트된 값은 반영되지 않습니다.
(2) 함수 성분 밖에 있는 변수
Initialization
: 파일이 로드되었을 때만 변수가 초기화됩니다.또한 파일로부터의 내보내기를 소비하는 컴포넌트의 수에 관계없이 파일은 한 번만 로드됩니다.이것이 useRef()를 사용하는 것과 비교한 주요 차이입니다.컴포넌트 인스턴스화가1개밖에 없는 경우 useRef()와 동일합니다.
Variable updates
: const 이외의 갱신 가능
Render
: React에 의해 트리거된 렌더가 없으므로 업데이트된 값은 반영되지 않습니다.
3. useState()에 의해 반환되는 상태 변수
Initialization
: 변수는 렌더링 수에 관계없이 컴포넌트가 마운트된 경우에만 초기화됩니다.그러나 각 구성 요소 인스턴스는 자체 상태 변수 복사본을 가져옵니다.
Variable updates
: 상태 업데이트 기능을 사용하여 업데이트할 수 있습니다.
Render
: 상태 변수가 갱신된 후 Render가 React에 의해 트리거됩니다(복수의 갱신은 1개의 렌더에 일괄 배치될 수 있습니다).
4. useRef()가 반환하는 변수(속성이 'current'인 객체)
Initialization
: 변수는 렌더링 수에 관계없이 컴포넌트가 마운트된 경우에만 초기화됩니다.단, 컴포넌트 외부에서 변수를 사용할 때 변수가 한 번만 발생하는 경우와 달리 각 컴포넌트 인스턴스에 대해 변수가 독립적으로 초기화됩니다.
Variable updates
: 'current' 속성을 사용하여 업데이트할 수 있습니다.
Render
: React에 의해 트리거된 렌더가 없으므로 업데이트된 값은 반영되지 않습니다.
상기 중 하나를 선택하는 것은 요건에 따라 크게 달라지지만, 툴박스에 필요한 툴이 준비되어 있어 거의 모든 사용 사례를 커버할 수 있습니다.
언급URL : https://stackoverflow.com/questions/57444154/why-need-useref-and-not-mutable-variable
'source' 카테고리의 다른 글
connectedRouter 오류: 상태 트리에서 라우터 리듀서를 찾을 수 없습니다. "router" 아래에 마운트해야 합니다. (0) | 2023.02.16 |
---|---|
잭슨 json을 사용하여 역직렬화를 위해 열거형 필드에 주석을 다는 방법 (0) | 2023.02.16 |
React.js: jsx를 JavaScript에서 분리하는 방법 (0) | 2023.02.16 |
@ConditionalOnProperty 주석의 목적은 무엇입니까? (0) | 2023.02.16 |
h2에 착신하는 screen_reader_text를_posts_pagination에서 삭제하려면 (0) | 2023.02.12 |