반응 후크의 oldValues와 newValues를 비교하는 방법 useEffect?
rate, sendAmount 및 receiveAmount의 3가지 입력이 있다고 칩시다.나는 그 3개의 입력을 useEffect 확산 파라미터에 넣었다.규칙은 다음과 같습니다.
- 변경된 sendAmount가 됩니다.
receiveAmount = sendAmount * rate
- receiveAmount를 합니다.
sendAmount = receiveAmount / rate
- 비율이 바뀌면 는 계산한다.
receiveAmount = sendAmount * rate
때sendAmount > 0
내가 계산한다.sendAmount = receiveAmount / rate
때receiveAmount > 0
다음은 문제를 나타내는 코드 및 박스 https://codesandbox.io/s/pkl6vn7x6j 입니다.
요?oldValues
★★★★★★★★★★★★★★★★★」newValues
좋아하다componentDidUpdate
3시?
감사해요.
.usePrevious
https://codesandbox.io/s/30n01w2r06https.io/s/30n01w2r06
저는 으로 사용할 수 .useEffect
각 변경이 같은 네트워크콜로 이어지기 때문입니다.그래서 저도 쓰고 있어요.changeCount
변경내용을 추적할 수 있습니다. ★★★★★★★★★★★★★★★★★.changeCount
로컬로부터의 변경만 추적하기 때문에 서버로부터의 변경으로 인한 불필요한 네트워크콜을 방지할 수 있습니다.
useRef를 사용하여 사용자 지정 후크를 작성하여 이전 소품을 제공할 수 있습니다.
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
에 하세요.useEffect
const Component = (props) => {
const {receiveAmount, sendAmount } = props
const prevAmount = usePrevious({receiveAmount, sendAmount});
useEffect(() => {
if(prevAmount.receiveAmount !== receiveAmount) {
// process here
}
if(prevAmount.sendAmount !== sendAmount) {
// process here
}
}, [receiveAmount, sendAmount])
}
두 개의 ,, 개, 개, 2, 개, 개, 개, 2, ,, , 개, to, two, to, to, to, to, to, to, however, to, however, to, to, to, to, to, to, to, to, however, however, however, however, however,useEffect
변경 한다.
을 있는 usePrevious
:
①의 .tsx
★★★★
import { useEffect, useRef } from "react";
const usePrevious = <T extends unknown>(value: T): T | undefined => {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
});
return ref.current;
};
또 에,.ts
★★★★
import { useEffect, useRef } from "react";
const usePrevious = <T>(value: T): T | undefined => {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
});
return ref.current;
};
옵션 1 - 값이 변경되면 useEffect 실행
const Component = (props) => {
useEffect(() => {
console.log("val1 has changed");
}, [val1]);
return <div>...</div>;
};
옵션 2 - useHasChanged 훅
현재 값을 이전 값과 비교하는 것은 일반적인 패턴이며 구현 세부 정보를 숨기는 자체 사용자 지정 후크를 정당화합니다.
const Component = (props) => {
const hasVal1Changed = useHasChanged(val1)
useEffect(() => {
if (hasVal1Changed ) {
console.log("val1 has changed");
}
});
return <div>...</div>;
};
const useHasChanged= (val: any) => {
const prevVal = usePrevious(val)
return prevVal !== val
}
const usePrevious = (value) => {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
커스텀 훅이 필요 없는 대체 솔루션인 인정된 답변에서 벗어나는 방법:
const Component = ({ receiveAmount, sendAmount }) => {
const prevAmount = useRef({ receiveAmount, sendAmount }).current;
useEffect(() => {
if (prevAmount.receiveAmount !== receiveAmount) {
// process here
}
if (prevAmount.sendAmount !== sendAmount) {
// process here
}
return () => {
prevAmount.receiveAmount = receiveAmount;
prevAmount.sendAmount = sendAmount;
};
}, [receiveAmount, sendAmount]);
};
이는 "여기에 프로세스" 비트에 있는 모든 값에 대해 실제로 이전 값을 참조해야 한다고 가정합니다. 조건 이 스트레이트(를 한!==
여기서 가장 심플한 솔루션은 다음과 같습니다.
const Component = ({ receiveAmount, sendAmount }) => {
useEffect(() => {
// process here
}, [receiveAmount]);
useEffect(() => {
// process here
}, [sendAmount]);
};
방금 리액트-델타를 발표했는데 이런 종류의 시나리오를 해결했어요제 생각에는useEffect
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
책임
- 내의 합니다.
Object.is
- #1의 결과에 따라 효과/청소 콜백을 실행합니다.
책임의 분할
react-delta
useEffect
훅을 끼우다
책임 #1
usePrevious(value)
useLatest(value)
useDelta(value, options)
useDeltaArray(valueArray, options)
useDeltaObject(valueObject, options)
some(deltaArray)
every(deltaArray)
책임 #2
, 이은 더합니다.useEffect
/useRef
★★★★★★★★★★★★★★★★★★.
원하신다면useEffect
「 」 「 」:
const usePreviousEffect = (fn, inputs = []) => {
const previousInputsRef = useRef([...inputs])
useEffect(() => {
fn(previousInputsRef.current)
previousInputsRef.current = [...inputs]
}, inputs)
}
그리고 이렇게 사용하세요.
usePreviousEffect(
([prevReceiveAmount, prevSendAmount]) => {
if (prevReceiveAmount !== receiveAmount) // side effect here
if (prevSendAmount !== sendAmount) // side effect here
},
[receiveAmount, sendAmount]
)
처음 효과를 실행할 때 이전 값이 사용자에게 전달되는 것에 주의해 주세요.fn
초기 입력값과 동일합니다.이것은 값이 변경되지 않은 상태에서 작업을 수행하려는 경우에만 문제가 됩니다.
되어 있지 않기 할 수 .useEffect
, 를 들어 ""를 사용하여 저장하십시오.useRef
상태가 사용 에 상태 되었을 수 setState
이치노
은 이, this, 적, 의 좋은 활용 사례입니다.useReducer
Redux와 같은 저장소를 제공하고 각각의 패턴을 구현할 수 있습니다.상태 업데이트는 명시적으로 수행되므로 어떤 상태 속성이 업데이트되는지 확인할 필요가 없습니다. 이는 이미 디스패치된 액션에서 명확합니다.
다음은 예를 제시하겠습니다.
function reducer({ sendAmount, receiveAmount, rate }, action) {
switch (action.type) {
case "sendAmount":
sendAmount = action.payload;
return {
sendAmount,
receiveAmount: sendAmount * rate,
rate
};
case "receiveAmount":
receiveAmount = action.payload;
return {
sendAmount: receiveAmount / rate,
receiveAmount,
rate
};
case "rate":
rate = action.payload;
return {
sendAmount: receiveAmount ? receiveAmount / rate : sendAmount,
receiveAmount: sendAmount ? sendAmount * rate : receiveAmount,
rate
};
default:
throw new Error();
}
}
function handleChange(e) {
const { name, value } = e.target;
dispatch({
type: name,
payload: value
});
}
...
const [state, dispatch] = useReducer(reducer, {
rate: 2,
sendAmount: 0,
receiveAmount: 0
});
...
대부분의 투표된 답변에 주의하세요.에서는, 「」의 바리에이션에 대해 설명합니다.usePrevious
에서는, 너무 많은 리다이렉트(1) 또는 원래의(2)와 같은 값을 얻을 수 있습니다.
다음과 같은 것이 필요합니다.
[value]
관계로서useEffect
value
사항- 「」의 할당
JSON.parse(JSON.stringify(value))
딥 카피) ('Deep Copy')ref.current
말하다useEffect
하기
업그레이드된 후크:
const usePrevious = <T>(value: T): T => {
const ref: any = useRef<T>()
useEffect(() => {
ref.current = JSON.parse(JSON.stringify(value))
}, [value])
return ref.current
}
여기 제가 사용하는 커스텀 훅이 있습니다.사용하는 것보다 직관적이라고 생각합니다.
import { useRef, useEffect } from 'react'
// useTransition :: Array a => (a -> Void, a) -> Void
// |_______| |
// | |
// callback deps
//
// The useTransition hook is similar to the useEffect hook. It requires
// a callback function and an array of dependencies. Unlike the useEffect
// hook, the callback function is only called when the dependencies change.
// Hence, it's not called when the component mounts because there is no change
// in the dependencies. The callback function is supplied the previous array of
// dependencies which it can use to perform transition-based effects.
const useTransition = (callback, deps) => {
const func = useRef(null)
useEffect(() => {
func.current = callback
}, [callback])
const args = useRef(null)
useEffect(() => {
if (args.current !== null) func.current(...args.current)
args.current = deps
}, deps)
}
사용할 수 있습니다.useTransition
다음과 같이 합니다.
useTransition((prevRate, prevSendAmount, prevReceiveAmount) => {
if (sendAmount !== prevSendAmount || rate !== prevRate && sendAmount > 0) {
const newReceiveAmount = sendAmount * rate
// do something
} else {
const newSendAmount = receiveAmount / rate
// do something
}
}, [rate, sendAmount, receiveAmount])
도움이 됐으면 좋겠다.
매우 간단한 소품 비교를 위해useEffect
쉽게 확인할 수 있습니다.
const myComponent = ({ prop }) => {
useEffect(() => {
---Do stuffhere----
}, [prop])
}
useEffect
그러면 프로펠이 변경된 경우에만 코드가 실행됩니다.
Ref를 사용하면 새로운 버그가 앱에 도입됩니다.
그럼 이 .usePrevious
「 」 「 」 、 「 」 。
- prop.min Time: 5 == > ref.current = 5 | ref.current 설정
- prop.min Time: 5 == > ref.current = 5 | 새 값은 ref.current와 동일합니다.
- prop.min Time: 8 ==> ref.current = 5 | 새 값이 ref.current와 같지 않습니다.
- prop.min Time: 5 == > ref.current = 5 | 새 값은 ref.current와 동일합니다.
알 수 있듯이 있지 않습니다.ref
는 '우리'를 사용하고 때문입니다.useEffect
useState가 아닌 useImer를 사용하여 상태에 액세스할 수 있습니다.예: https://css-tricks.com/build-a-chat-app-using-react-hooks-in-100-lines-of-code/
나는 위의 어떤 대답도 마음에 들지 않았고, 나는 일련의 부란을 통과할 수 있는 능력을 원했고, 만약 그 중 하나가 사실이라면, 그래서 다시 연마할 수 있다.
/**
* effect fires if one of the conditions in the dependency array is true
*/
export const useEffectCompare = (callback: () => void, conditions: boolean[], effect = useEffect) => {
const shouldUpdate = useRef(false);
if (conditions.some((cond) => cond)) shouldUpdate.current = !shouldUpdate.current;
effect(callback, [shouldUpdate.current]);
};
//usage - will fire because one of the dependencies is true.
useEffectCompare(() => {
console.log('test!');
}, [false, true]);
여기 타이프스크립트 버전 Aadit M Shah's Answer가 있습니다.
을 에에이 i i i i i i i i i i 。useTransition
로로 합니다.usePrevious
useTransition
반응하다
import { useEffect, useRef, useState } from 'react';
const usePrevious = <T extends any[],>(callback: (prev: T) => void, deps: T): void => {
const callbackRef = useRef<null | ((prev: T) => void)>(null);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
const depsRef = useRef<null | T>(null);
const [initial, setInitial] = useState(true);
useEffect(() => {
if (!initial && depsRef.current !== null && callbackRef.current !== null) {
callbackRef.current(depsRef.current);
}
depsRef.current = deps;
setInitial(false);
}, deps);
}
export default usePrevious;
사용방법:
usePrevious<[boolean]>(([prevIsOpen]) => {
console.log('prev', prevIsOpen);
console.log('now', isOpen);
}, [isOpen])
사용자의 경우(단순 객체):
useEffect(()=>{
// your logic
}, [rate, sendAmount, receiveAmount])
그 외의 경우(복잡한 객체)
const {cityInfo} = props;
useEffect(()=>{
// some logic
}, [cityInfo.cityId])
언급URL : https://stackoverflow.com/questions/53446020/how-to-compare-oldvalues-and-newvalues-on-react-hooks-useeffect
'programing' 카테고리의 다른 글
각도 JS: js 파일을 부분적으로 로드하는 방법 (0) | 2023.03.12 |
---|---|
자동 추가 제거자동 추가 제거문자 그대로의 내용이 없는 페이지(숏 코드 사용)에서 (0) | 2023.03.12 |
JSON.stringify에서 기능을 유지할 수 있습니까? (0) | 2023.03.12 |
개인 방법 Jasmine을 사용한 단위 테스트 (0) | 2023.03.12 |
ORACLE의 select 문에서 데이터 유형 필드 가져오기 (0) | 2023.03.12 |