我在 react native 中有一個 react 組件,我想手動處理 hardwareBackButton。當傳遞給hardwareBackPressListener的backHandler函式中的redux狀態為真或假時,我有不同的行為。
const brandSelected = useSelector(state => state.map.brandSelected);
我的組件中有這個 useSelector 來訪問狀態。并且我有 useEffect 函式來監視此狀態的變化:(當狀態變為真或假時,它可以正常作業并記錄狀態。
React.useEffect(() => {
console.log(brandSelected); // this is false correctly
}, [brandSelected]);
最后我有一個 backHandler 函式,我將它傳遞給 hardwareBackPress 監聽器。
React.useEffect(() => {
BackHandler.addEventListener('hardwareBackPress', backHandler);
return () => {
BackHandler.removeEventListener('hardwareBackPress', backHandler);
};
}, []);
和 backHandler 函式:
const backHandler = () => {
console.log('check, backhandler', brandSelected) // it logs true continuously
if (brandSelected === true) {
dispatch(
dispatchItemToRedux({
type: CATEGORIES_SELECTION,
payload: {
brandSelected: false,
},
}),
);
return true;
}
popScreen(Screens.Map);
return true;
};
但是這個函式不會通知brandSelected 狀態改變了。第一次它正常作業,調度功能并正確更改 redux 狀態,并且 useEffect 功能正確記錄錯誤。但在其他嘗試中它不能正常作業并且沒有任何改變!!
uj5u.com熱心網友回復:
這里的問題是您在初始渲染周期傳遞給事件偵聽器brandSelected的backHandler函式中的陳舊外殼"hardwareBackPress"。backHandler函式只擁有初始渲染周期中的值,并且永遠不會更新/重新封裝更新的值。
要解決此問題,您應該將backHandler狀態值快取在可以在回呼處理程式中參考的 React ref 中。
const brandSelected = useSelector(state => state.map.brandSelected);
const brandSelectedRef = React.useRef(brandSelected);
useEffect(() => {
brandSelectedRef.current = brandSelected;
}, [brandSelected]);
...
const backHandler = () => {
console.log('check, backhandler', brandSelectedRef.current)
if (brandSelectedRef.current) {
dispatch(
dispatchItemToRedux({
type: CATEGORIES_SELECTION,
payload: {
brandSelected: false,
},
}),
);
return true;
}
popScreen(Screens.Map);
return true;
};
另一種方法是移動backHandler 到所述useEffect鉤設定事件偵聽器,并使用brandSelected狀態作為依賴所以更新的狀態值是重新封閉在回呼。
React.useEffect(() => {
const backHandler = () => {
console.log('check, backhandler', brandSelected)
if (brandSelected) {
dispatch(
dispatchItemToRedux({
type: CATEGORIES_SELECTION,
payload: {
brandSelected: false,
},
}),
);
return true;
}
popScreen(Screens.Map);
return true;
};
BackHandler.addEventListener('hardwareBackPress', backHandler);
return () => {
BackHandler.removeEventListener('hardwareBackPress', backHandler);
};
}, [brandSelected]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/386480.html
下一篇:基于圖示而不是文本均勻間隔
