如何在RTK中存储函数引用,实现React跨组件重置Idle Timer
在React项目中通过Redux Toolkit存储react-idle-timer的reset函数并跨组件调用
我需要在React项目中利用Redux Toolkit(RTK)存储函数引用,将Home组件里react-idle-timer的reset函数存入Redux状态,让其他组件可以调用该函数重置空闲计时器。以下是我的实现尝试及修正方案:
现有代码问题分析
- Slice reducer参数错误:
setLogoutTimerReset的第二个参数是action对象,需通过action.payload获取传入的函数,而非直接使用payload变量。 - Home组件依赖缺失:
useEffect的依赖数组为空,无法追踪reset函数的更新,导致Redux中存储的可能不是最新的函数引用。 - 调用安全性不足:其他组件直接调用Redux中的函数时,未做有效性判断,初始空函数调用虽不报错,但严谨性不足。
修正后的代码实现
1. 修正Logout Slice代码
import { createSlice } from "@reduxjs/toolkit"; const initialState = { resetLogoutTimer: () => {}, }; export const logoutSlice = createSlice({ name: "logout", initialState, reducers: { setLogoutTimerReset: (state, action) => { // 通过action.payload获取传入的reset函数 state.resetLogoutTimer = action.payload; }, }, }); export const { setLogoutTimerReset } = logoutSlice.actions; export default logoutSlice.reducer;
2. 修正Home组件代码
import React, { useEffect } from "react"; import { Outlet } from "react-router-dom"; import { useSelector, useDispatch } from "react-redux"; import Sidebar from "../components/Sidebar/Sidebar"; import { useIdleTimer } from "react-idle-timer"; import { userLogout } from "../utils/utils"; import LoadingAnimation from "../components/LoadingAnimation/LoadingAnimation"; import { setLogoutTimerReset } from "../store/slicers/logoutSlice"; const Home = () => { const { user } = useSelector((state) => state.auth); const dispatch = useDispatch(); const onIdle = () => { userLogout(); }; const { reset } = useIdleTimer({ onIdle, timeout: 60 * 30 * 1000, // 30分钟空闲超时 }); useEffect(() => { dispatch(setLogoutTimerReset(reset)); }, [dispatch, reset]); // 添加依赖,确保函数更新时同步到Redux return user ? ( <section className="home-sidebar-flex"> <Sidebar /> <main className="map-main-parent--container"> <Outlet /> </main> </section> ) : ( <LoadingAnimation /> ); }; export default Home;
3. 其他调用组件优化代码
import React from 'react' import { useSelector } from "react-redux"; function ResetTimerButton() { const { resetLogoutTimer } = useSelector((state) => state.logoutState); const handleReset = () => { // 先判断函数有效性再调用 if (typeof resetLogoutTimer === 'function') { resetLogoutTimer(); } }; return ( <div onClick={handleReset}>重置空闲计时器</div> ) } export default ResetTimerButton;
关键说明
- Redux Toolkit支持在状态中存储函数引用,但需注意函数的更新时机,通过
useEffect依赖追踪确保Redux中始终存储最新的reset函数。 - 调用前判断函数类型是为了规避初始状态下空函数的潜在风险,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Mubasher Mukhtar
相关产品推荐
相关产品推荐

