리액트 후크를 사용한 componentDidUpdate와 동등
tldr; 시뮬레이션 방법componentDidUpdate또는 그 이외의 방법으로key컴포넌트를 강제로 리셋할 수 있는 어레이가 있는 소품입니까?
타이머를 표시하고 0에 도달하면 콜백을 실행하는 컴포넌트를 실장하고 있습니다.이 목적은 콜백이 오브젝트 목록을 갱신하는 것입니다.후자의 컴포넌트는 새로운 리액트 훅으로 구성되어 있습니다. useState그리고.useEffect.
그state에 타이머가 시작된 시각과 남은 시간을 나타냅니다.그effect는 남은 시간을 갱신하고 콜백을 호출해야 하는지 여부를 확인하기 위해 매초 호출 간격을 설정합니다.
이 컴포넌트는 타이머를 재스케줄 하거나 제로 상태가 되었을 때 인터벌을 계속하는 것이 아니라 콜백과 아이돌을 실행합니다.타이머를 리프레시하기 위해 어레이를 다음 주소로 전달하고 싶었습니다.key컴포넌트 상태가 리셋 되어 타이머가 재기동합니다.불행하게도key는 문자열과 함께 사용해야 하므로 배열 참조가 변경되었는지 여부에 관계없이 아무런 영향을 미치지 않습니다.
또, 마음에 드는 배열을 통과시켜 소품 변경을 실시하려고 했지만, 상태가 유지되어 간격이 리셋 되지 않았습니다.
새로운 훅 API만을 사용하여 상태를 강제로 업데이트하기 위해 어레이의 얕은 변화를 관찰하는 데 권장되는 방법은 무엇입니까?
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
function getTimeRemaining(startedAt, delay) {
const now = new Date();
const end = new Date(startedAt.getTime() + delay);
return Math.max(0, end.getTime() - now.getTime());
}
function RefresherTimer(props) {
const [startedAt, setStartedAt] = useState(new Date());
const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));
useEffect(() => {
if (timeRemaining <= 0) {
// The component is set to idle, we do not set the interval.
return;
}
// Set the interval to refresh the component every second.
const i = setInterval(() => {
const nowRemaining = getTimeRemaining(startedAt, props.delay);
setTimeRemaining(nowRemaining);
if (nowRemaining <= 0) {
props.callback();
clearInterval(i);
}
}, 1000);
return () => {
clearInterval(i);
};
});
let message = `Refreshing in ${Math.ceil(timeRemaining / 1000)}s.`;
if (timeRemaining <= 0) {
message = 'Refreshing now...';
}
return <div>{message}</div>;
}
RefresherTimer.propTypes = {
callback: PropTypes.func.isRequired,
delay: PropTypes.number
};
RefresherTimer.defaultProps = {
delay: 2000
};
export default RefresherTimer;
에서 사용하려고 했다.key:
<RefresherTimer delay={20000} callback={props.updateListOfObjects} key={listOfObjects} />
소품 변경 시 사용 시도:
<RefresherTimer delay={20000} callback={props.updateListOfObjects} somethingThatChanges={listOfObjects} />
listOfObjects오브젝트 자체를 변경할 필요는 없기 때문에 어레이와 비교할 필요가 있습니다.!==일반적으로 이 값은Redux, 액션이 있는 경우updateListOfObjects어레이가 다음과 같이 재초기화됩니다.newListOfObjects = [...listOfObjects].
그useRef는 기능 컴포넌트에 "변수"를 작성합니다.상태를 업데이트하지 않고 마운트 단계인지 업데이트 단계인지를 나타내는 플래그 역할을 합니다.
const mounted = useRef();
useEffect(() => {
if (!mounted.current) {
// do componentDidMount logic
mounted.current = true;
} else {
// do componentDidUpdate logic
}
});
즉, 어레이의 참조가 변경되었을 때 타이머를 리셋하고 싶은 것입니다.그렇다면, 몇 가지 확산 메커니즘을 사용할 필요가 있습니다.순수한 훅 기반 솔루션은 다음의 두 번째 파라미터를 이용할 수 있습니다.useEffect다음과 같은 경우:
function RefresherTimer(props) {
const [startedAt, setStartedAt] = useState(new Date());
const [timeRemaining, setTimeRemaining] = useState(getTimeRemaining(startedAt, props.delay));
//reset part, lets just set startedAt to now
useEffect(() => setStartedAt(new Date()),
//important part
[props.listOfObjects] // <= means: run this effect only if any variable
// in that array is different from the last run
)
useEffect(() => {
// everything with intervals, and the render
})
}
이 동작에 대한 자세한 내용은http://https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects 를 참조해 주세요.
커스텀 훅을 사용하다
export const useComponentDidUpdate = (effect, dependencies) => {
const hasMounted = useRef(false);
useEffect(
() => {
if (!hasMounted.current) {
hasMounted.current = true;
return;
}
effect();
},
dependencies
);
};
초기 렌더링 후에는 효과가 실행되지 않습니다.그 후 관찰해야 할 값의 배열에 따라 달라집니다.비어 있는 경우 모든 렌더링 후에 실행됩니다.그렇지 않으면 값 중 하나가 변경되었을 때 실행됩니다.
먼저 후크 만들기
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
이제 주요 기능에서
import React, {useEffect, useState} from 'react';
import {Text, View} from 'react-native';
import usePrevious from './usePrevious';
export default function Example() {
const [count, setCount] = useState(0);
const prevCount = usePrevious(count);
useEffect(() => {
// this one is your didupdate method for count variable
if (count != prevCount) {
alert('count updated')
}
}, [count]);
return (
<View>
<Text>
You clicked {count} times {prevCount}{' '}
</Text>
<Text onPress={() => setCount(count + 1)}>Increment</Text>
<Text onPress={() => setCount(count - 1)}>Decrement</Text>
</View>
);
}
다음에서 사용할 수 있습니다.react-use.
Universal TypeScript 버전:
import { DependencyList, useEffect, useRef } from "react"
type Destructor = () => void
type MountEffectCallback = (firstLoad: boolean) => (void | Destructor)
export const useDidUpdateEffect = (effect: MountEffectCallback, deps: DependencyList) => {
const firstLoad = useRef(true)
useEffect(() => {
effect(firstLoad.current)
if (firstLoad.current) {
firstLoad.current = false
}
}, deps)
}
방법은 를 제공하는 입니다.key 에 만약 문자열로 강제되면listOfObjects입니다. "이러한 문자열"이 key으로 listOfObjects.toString().
수 를 들어, 임의의 키를 사용할 수 있습니다.uuid ★★★★★★★★★★★★★★★★★」Math.random()·················의 얄팍한 listOfObjects부모 컴포넌트에서 수행하여 새 키를 제공할 수 있습니다. useMemo하기 위해 할 수 있습니다.또, 「재마운트키는, 「재마운트키」를 갱신할 수 있습니다.listOfObjects메모해야 할 파라미터 목록으로 사용할 수 있습니다.다음은 예를 제시하겠습니다.
const remountKey = useMemo(() => Math.random(), listOfObjects);
return (
<div>
<RefresherTimer delay={3000} callback={() => console.log('refreshed')} key={remountKey} />
</div>
);
키 재마운트 대신 자 컴포넌트는 자신의 상태를 리셋하고 콜백을 노출하여 리셋을 트리거할 수 있습니다.
★★★★★★★★★★★★★★★★★★★★★의 얕은 비교listOfObjects부모 컴포넌트의 실장을 인식할 필요가 있기 때문에 내부 자식 컴포넌트는 반대가 됩니다.
언급URL : https://stackoverflow.com/questions/53255951/equivalent-to-componentdidupdate-using-react-hooks
'programing' 카테고리의 다른 글
| WordPress get_template_part pass 변수 (0) | 2023.03.31 |
|---|---|
| WP에서 업로드된 미디어를 어떻게 구성합니까? (0) | 2023.03.31 |
| ReactJS 구성 요소 이름은 대문자로 시작해야 합니까? (0) | 2023.03.31 |
| javascript 및 Postman을 사용한 JSON 배열 레코드 카운트 (0) | 2023.03.31 |
| window을 하지 않고 합니다.window을 하지 않고 합니다.window을 하지 않고 합니다. (0) | 2023.03.31 |