![](/img/trans.png)
[英]React hooks value renders correctly but not updated inside a callback function of addEventListener
[英]Not getting updated hooks value inside function
未在由 eventListener 觸發的函數中獲取狀態的更新值。 甚至嘗試使用后台計時器。 會有什么問題?
displayIncomingCall() // this function gets called from UI.
const callApp = () => {
const [calls, setCalls] = useState({});
const addCall = (key, value) => {
setCalls({ ...calls, [key]: value });
};
const displayIncomingCall = number => {
const callUUID = getCurrentCallId();
addCall(callUUID, number);
...
};
const onAnswerCall = () => {
console.log('=== onAnswerCall ::: ===', calls); <--- always initial value. Not getting updated one.
}
useEffect(() => {
console.log('=== useEffect ::: ===', calls); // getting updated value
}, [calls]);
useEffect(() => {
RNCallKeep.addEventListener('answerCall', onAnswerCall);
return () => {
RNCallKeep.removeEventListener('answerCall', onAnswerCall);
};
}, []);
console.log('=== parent ::: ===', calls); // getting updated value
return (...)
}
onAnswerCall
只在useEffect
回調中被引用,而useEffect
回調有一個空的依賴數組,所以它只在初始掛載上運行。 每當onAnswerCall
被calls
,它可以看到的calls
綁定在一個舊的閉包中。
使用 ref 而不是 state:
const callsRef = useRef({});
const addCall = (key, value) => {
callsRef.current[key] = value;
};
const onAnswerCall = () => {
console.log('=== onAnswerCall ::: ===', callsRef.current);
}
如果calls
需要處於狀態以便其更改導致重新渲染,那么您可以同時使用狀態和引用,並在調用setCalls
時分配給引用,或者您可以從useEffect
刪除依賴數組,因此在每次渲染時向RNCallKeep
添加和刪除偵聽器。
React hooks state 不保留任何狀態數據,您必須使用useCallback
和set*
state 函數中的先前狀態來跟上您的狀態:
const callApp = () => {
const [calls, setCalls] = useState({});
const addCall = (key, value) => {
// Use previous state provided to update the state
setCalls(calls => ({ ...calls, [key]: value }));
};
const displayIncomingCall = number => {
const callUUID = getCurrentCallId();
addCall(callUUID, number);
...
};
// Use useCallback to keep up with the state
const onAnswerCall = useCallback(() => {
console.log('=== onAnswerCall ::: ===', calls); <--- Will get updated
}, [calls]);
useEffect(() => {
console.log('=== useEffect ::: ===', calls); // getting updated value
}, [calls]);
useEffect(() => {
RNCallKeep.addEventListener('answerCall', onAnswerCall);
return () => {
RNCallKeep.removeEventListener('answerCall', onAnswerCall);
};
}, [onAnswerCall]);
console.log('=== parent ::: ===', calls); // getting updated value
return (...)
}
您的事件偵聽器回調在calls
的初始狀態下關閉。 將其添加為效果的依賴項,並且每次其值更改時您都應該注冊一個新的偵聽器(並刪除舊的偵聽器)。
編輯:實際上,您應該將整個onAnswerCall
函數移動到效果中,因為它只在那里使用:
useEffect(() => {
const onAnswerCall = () => {
console.log('=== onAnswerCall ::: ===', calls);
};
RNCallKeep.addEventListener('answerCall', onAnswerCall);
return () => {
RNCallKeep.removeEventListener('answerCall', onAnswerCall);
};
}, [calls]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.