不确定这种预期的行为,但是我正在尝试使用React Navigation,React Native和Redux Toolkit保持页面导航之间的状态。
所以我有一个全屏水平滚动列表,一次有一个元素可见,为了跟踪可见的页面,我正在跟踪视图/数组中该元素的活动索引。
所以我有自己的状态:
type State = {
pages: Array<{ id, title, name }>,
activeIndex: number
}
每当用户滚动列表时,我都会看到新项目的索引并更新状态。
// page slice
const initialState: State = {
pages: undefined; // async call populates
activeIndex: 0;
}
const PageListSlice = createSlice({
name: 'State',
initialState,
reducers: {
setActivePage(
state: State,
action: PayloadAction<{ index: number }>,
) {
state.activeIndex = action.payload.index;
return state;
},
}
});
export const setActiveIndex = (activeIndex: number): AppThunk => async (
dispatch: AppDispatch,
) => {
dispatch(setLearnState({index: activeIndex}));
};
并在组件安装上加载状态:
export const ListPage: React.FC<Props> = ({ navigation }): JSX.Element => {
const dispatch: Dispatch<any> = useDispatch();
const pageListSlice: State = useSelector((state: RootState) => state.PageState);
useFocusEffect(
React.useCallback(() => {
console.log(pageListSlice.activeIndex); // always returns initial value of 0
}, []),
);
return (
// ...
);
}
现在的问题是,当我使用React Navigation将 back 导航到该页面时,现有状态被替换为初始状态。由于现有状态仍显示在屏幕上,因此令人困惑。我的意思是;我将导航回到列表中的正确项目(我以前曾在的位置),但是状态将不正确。状态返回到初始状态,因此即使我正在查看索引7处的屏幕,来自Redux的状态也是初始值0。
这是预期的行为吗?对我来说似乎很疯狂,不得不将状态存储在缓存中以在页面导航之间保持状态。
我已将状态加载到子组件中,并且存在正确的状态,因此当您导航到页面时,它似乎仅恢复到初始状态。我尝试使用useFocusEffect
加载状态/添加新的reducer进行触发,但这也会返回初始状态。
我已尝试尽可能简化此操作以隔离我所面临的问题。我希望这是有道理的。欢迎所有帮助,谢谢。
版本:
"@react-navigation/bottom-tabs": "^5.2.5",
"@react-navigation/native": "^5.1.4",
"@react-navigation/stack": "^5.2.9",
"@reduxjs/toolkit": "^1.4.0",
"expo": "^37.0.3",
"react": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.0.tar.gz",
"react-redux": "^7.2.0",
"redux-thunk": "^2.3.0"
答案 0 :(得分:1)
您的日志不正确,因为您已向React.useCallback
传递了一个空的依赖项数组,这意味着该回调永远不会更新以获取正确的值。
如果您将适当的依赖项数组传递给React.useCallback
(在这种情况下为pageListSlice.activeIndex
),则它将记录正确的值:
useFocusEffect(
React.useCallback(() => {
console.log(pageListSlice.activeIndex);
}, [pageListSlice.activeIndex])
)
您应该使用https://www.npmjs.com/package/eslint-plugin-react-hooks插件来捕获此类错误。