반응형
React ref.current 값이 변경되었는지 어떻게 알 수 있습니까?
보통 소품만 있으면 글씨를 쓸 수 있어요
componentDidUpdate(oldProps) {
if (oldProps.foo !== this.props.foo) {
console.log('foo prop changed')
}
}
소품 변화를 감지하기 위해.
하지만 만약 우리가React.createRef()
참조가 새로운 컴포넌트 또는 DOM 요소로 변경된 경우 어떻게 검출합니까?리액트 문서에서는 아무 말도 안 했어요
F.E.
class Foo extends React.Component {
someRef = React.createRef()
componentDidUpdate(oldProps) {
const refChanged = /* What do we put here? */
if (refChanged) {
console.log('new ref value:', this.someRef.current)
}
}
render() {
// ...
}
}
우리 스스로 가치 있는 것을 구현해야 하나요?
F.E.
class Foo extends React.Component {
someRef = React.createRef()
oldRef = {}
componentDidMount() {
this.oldRef.current = this.someRef.current
}
componentDidUpdate(oldProps) {
const refChanged = this.oldRef.current !== this.someRef.current
if (refChanged) {
console.log('new ref value:', this.someRef.current)
this.oldRef.current = this.someRef.current
}
}
render() {
// ...
}
}
그게 우리가 해야 할 일인가요?리액트라면 이런 걸 쉽게 만들 수 있을 줄 알았는데
리액트 문서에서는 콜백 참조를 사용하여 검출할 것을 권장합니다.ref
값이 변화합니다.
훅
export function Comp() {
const onRefChange = useCallback(node => {
if (node === null) {
// DOM node referenced by ref has been unmounted
} else {
// DOM node referenced by ref has changed and exists
}
}, []); // adjust deps
return <h1 ref={onRefChange}>Hey</h1>;
}
useCallback
를 사용하여 참조 콜백의 이중 콜을 방지합니다.null
그리고 요소.
현재 DOM 노드를 다음과 같이 저장하여 변경 시 재렌더를 트리거할 수 있습니다.useState
:
const [domNode, setDomNode] = useState(null);
const onRefChange = useCallback(node => {
setDomNode(node); // trigger re-render on changes
// ...
}, []);
클래스 컴포넌트
export class FooClass extends React.Component {
state = { ref: null, ... };
onRefChange = node => {
// same as Hooks example, re-render on changes
this.setState({ ref: node });
};
render() {
return <h1 ref={this.onRefChange}>Hey</h1>;
}
}
주의: 알림 없음ref
변화들.또, 로는 운이 없다.React.createRef()
/ object refs.
다음은 테스트 케이스입니다.이 테스트 케이스는 노드를 폐기하고 재추가하면서onRefChange
콜백:
const Foo = () => {
const [ref, setRef] = useState(null);
const [removed, remove] = useState(false);
useEffect(() => {
setTimeout(() => remove(true), 3000); // drop after 3 sec
setTimeout(() => remove(false), 5000); // ... and mount it again
}, []);
const onRefChange = useCallback(node => {
console.log("ref changed to:", node);
setRef(node); // or change other state to re-render
}, []);
return !removed && <h3 ref={onRefChange}>Hello, world</h3>;
}
ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.1/umd/react.production.min.js" integrity="sha256-vMEjoeSlzpWvres5mDlxmSKxx6jAmDNY4zCt712YCI0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.1/umd/react-dom.production.min.js" integrity="sha256-QQt6MpTdAD0DiPLhqhzVyPs1flIdstR4/R7x4GqCvZ4=" crossorigin="anonymous"></script>
<script> var {useState, useEffect, useCallback} = React</script>
<div id="root"></div>
componentDidUpdate
컴포넌트 상태 또는 소품이 변경되었을 때 호출되기 때문에 반드시 호출되는 것은 아닙니다.ref
변이될 수 있기 때문에 변화합니다.
참조가 이전 렌더에서 변경되었는지 확인하려면 실제 참조와 대조하여 확인하는 다른 참조를 유지할 수 있습니다.
예
class App extends React.Component {
prevRef = null;
ref = React.createRef();
state = {
isVisible: true
};
componentDidMount() {
this.prevRef = this.ref.current;
setTimeout(() => {
this.setState({ isVisible: false });
}, 1000);
}
componentDidUpdate() {
if (this.prevRef !== this.ref.current) {
console.log("ref changed!");
}
this.prevRef = this.ref.current;
}
render() {
return this.state.isVisible ? <div ref={this.ref}>Foo</div> : null;
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
언급URL : https://stackoverflow.com/questions/55838351/how-do-we-know-when-a-react-ref-current-value-has-changed
반응형
'programing' 카테고리의 다른 글
C++에서 json 파일을 읽는 중 (0) | 2023.02.10 |
---|---|
WP Rest API 업로드 이미지 (0) | 2023.02.10 |
브라우저에서 angularjs의 $rootScope 개체를 디버깅하는 방법 (0) | 2023.02.10 |
JSON 경유 HTML 코드 전송 (0) | 2023.02.10 |
Angular js - ng-repeat이 비어 있는 경우 메시지 표시 (0) | 2023.02.10 |