react useEffect 폐쇄 된 구덩이
useEffect 로 인 한 폐쇄 문제 코드 보기
const btn = useRef();
const [v, setV] = useState('');
useEffect(() => {
let clickHandle = () => {
console.log('v:', v);
}
btn.current.addEventListener('click', clickHandle)
return () => {
btn.removeEventListener('click', clickHandle)
}
}, []);
const inputHandle = e => {
setV(e.target.value)
}
return (
<>
<input value={v} onChange={inputHandle} />
<button ref={btn} > </button>
</>
)
useEffect 의 의존 항목 배열 이 비어 있 기 때문에 페이지 렌 더 링 이 완 료 된 후에 내부 코드 는 한 번 만 실행 되 고 페이지 가 소각 되 어 다시 실 행 됩 니 다.이 때 입력 상자 에 임의의 문 자 를 입력 하고 테스트 단 추 를 누 르 면 출력 이 비어 있 습 니 다.그 다음 에 어떤 문 자 를 입력 하고 테스트 단 추 를 누 르 면 출력 결과 가 비어 있 습 니 다.왜 이러 지?사실은 폐쇄 로 인 한 것 이다.
발생 원인
함수 의 역할 영역 은 함수 가 정 의 될 때 결정 된다.
btn 에 클릭 이 벤트 를 등록 할 때 역할 영역 은 다음 과 같 습 니 다.
접근 할 수 있 는 자유 변수 v 는 아직 비어 있 습 니 다.이벤트 가 실 행 될 때 클릭 반전 함 수 를 실행 합 니 다.이 때 실행 컨 텍스트 를 만 들 고 도 메 인 체인 을 실행 컨 텍스트 에 복사 합 니 다.
이 폐쇄 문제 에 대하 여 아래 에 대략 5 가지 해결 방법 을 제시 하 다.
1.할당 방식 으로 v 를 직접 수정 하고 v 를 수정 하 는 방법 을 useCallback 으로 감 싸 줍 니 다.
v 를 수정 하 는 방법 을 useCallback 으로 감 싸 면 useCallback 패키지 의 함수 가 캐 시 됩 니 다.의존 항목 의 배열 이 비어 있 기 때문에 여기 서 직접 값 을 부여 하 는 방식 으로 v 는 오래된 v 입 니 다.이 방법 은 추천 하지 않 습 니 다.setState 가 공식 적 으로 추천 하 는 state 를 수정 하 는 방식 이기 때문에 setV 를 사용 하 는 것 은 rerender 를 촉발 하기 위해 서 입 니 다.
// v const var,
var [v, setV] = useState('');
const inputHandle = useCallback(e => {
let { value } = e.target
v = value
setV(value)
}, [])
2.useEffect 의존 항목 에 v 추가이것 은 아마 대부분의 사람들 이 먼저 생각 하 는 방법 일 것 이다.v 가 오래된 것 이 라면 v 가 업 데 이 트 될 때마다 사건 을 다시 등록 하면 되 지 않 겠 는가?그러나 이런 것 은 매번 v 업데이트 가 다시 등록 되 어야 하고 이론 은 한 번 만 등록 해 야 하 는 사건 이 여러 번 이 되 어야 한다.
3.v 가 다시 밝 혀 지지 않도록
let 또는 var 방식 으로 v 대신 변 수 를 설명 하고 이 변 수 를 직접 수정 합 니 다.setState 관련 함수 가 render 를 촉발 하 는 것 이 아니 라 다시 설명 되 지 않 습 니 다.클릭 한 리 셋 함수 에서'최신'값 을 얻 을 수 있 습 니 다.그러나 이 방법 은 더욱 추천 하지 않 습 니 다.예 를 들 어 input 구성 요 소 는 rerender 가 없 기 때문에 처음부터 끝까지 빈 값 을 표시 합 니 다.조작 예상 에 부합 되 지 않 습 니 다.
4.useState 대신 useRef 사용
const btn = useRef();
const vRef = useRef('');
const [v, setV] = useStat('');
useEffect(() => {
let clickHandle = () => {
console.log('v:', vRef.current);
}
btn.current.addEventListener('click', clickHandle)
return () => {
btn.removeEventListener('click', clickHandle)
}
}, []);
const inputHandle = e => {
let { value } = e.target
vRef.current = value
setV(value)
}
return (
<>
<input value={v} onChange={inputHandle} />
<button ref={btn} > </button>
</>
)
useRef 의 방안 이 유효한 이 유 는 매번 input 의 change 가 vRef 라 는 대상 의 current 속성 을 수 정 했 기 때 문 입 니 다.vRef 는 항상 그 vRef 입 니 다.rerender 라 도 vRef 가 대상 이기 때문에 변 수 는 스 택 메모리 에 저 장 된 값 은 이 대상 이 메모리 에 저 장 된 주소 입 니 다.하나의 인용 일 뿐 대상 의 특정한 속성 만 수정 합 니 다.이 인용 은 변 하지 않 습 니 다.그래서 이벤트 의 역할 도 메 인 체인 을 클릭 하면 항상 같은 vRef 를 방문 합 니 다.5.v 를 대상 유형 으로 변경
사실 useRef 를 사용 하 는 것 과 마찬가지 로 대상 이 라면 어떤 속성 만 수정 해도 이 state 가 가리 키 는 주 소 를 바 꾸 지 않 습 니 다.
코드 주소
점여기,이곳테스트 코드 보기
여기 서 react useEffect 폐쇄 된 구덩이 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 react useEffect 폐쇄 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
nginx 에서 사이트 아이콘 표시 설정전단 개발 환경: react:^16.4.1 webpack:^4.16.0 웹 팩 에 favicon. ico 설정 추가: nginx 는 ico 에 대한 지원 을 추가 합 니 다:...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.