箭头函数不通知 redux 状态变化
Arrow function does not notify redux state changes
我在 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 Listener。
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 函数正确记录 false。但在其他尝试中它无法正常工作并且没有任何改变!!
这里的问题是您在初始渲染周期传递给 "hardwareBackPress"
事件侦听器的 backHandler
函数中 brandSelected
的陈旧外壳。 backHandler
函数仅具有初始渲染周期的值,永远不会 update/re-enclose 更新值。
要解决这个问题,您应该将 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]);
我在 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 Listener。
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 函数正确记录 false。但在其他尝试中它无法正常工作并且没有任何改变!!
这里的问题是您在初始渲染周期传递给 "hardwareBackPress"
事件侦听器的 backHandler
函数中 brandSelected
的陈旧外壳。 backHandler
函数仅具有初始渲染周期的值,永远不会 update/re-enclose 更新值。
要解决这个问题,您应该将 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]);