react-router-dom 6.4.2:生产环境useNavigate传函数返回null问题
问题场景
使用react-router-dom ^6.4.2时,通过useNavigate的state传递函数到目标组件,本地开发环境正常,但生产环境中函数变为null。
源组件代码:
navigate("/confirmationScreen", { state: { confirmFunction: handleCreateTransaction, redirect: "/wallet", }, });
目标组件代码:
const {state} = useLocation(); state.confirmFunction; // 生产环境返回null
原因分析
- 生产环境下,路由
state通常会被强制做JSON序列化处理,而函数属于不可序列化的引用类型,序列化过程中会被直接丢弃,最终变为null。 - 本地开发环境一般没有强制序列化
state的逻辑,所以函数可以正常传递。 - React Router官方明确不建议通过
state传递非可序列化数据(如函数、Symbol、循环引用对象等)。
解决方案
方案1:使用全局状态管理(推荐)
把跨组件调用的函数放到React Context或状态管理库(如Zustand、Redux)中,目标组件直接从全局获取函数,避免通过路由state传递。
示例:React Context实现
- 创建交易上下文:
import { createContext, useContext, useCallback } from 'react'; const TransactionContext = createContext(null); export const TransactionProvider = ({ children }) => { // 用useCallback保证函数引用稳定 const handleCreateTransaction = useCallback(async () => { // 这里编写你的创建交易逻辑 console.log('执行创建交易操作'); // 比如调用后端API、更新本地状态等 }, []); return ( <TransactionContext.Provider value={{ handleCreateTransaction }}> {children} </TransactionContext.Provider> ); }; // 自定义Hook简化上下文调用 export const useTransaction = () => useContext(TransactionContext);
- 源组件(仅传递非函数数据):
import { useNavigate } from "react-router-dom"; const SourceComponent = () => { const navigate = useNavigate(); const proceed = () => { navigate("/confirmationScreen", { state: { redirect: "/wallet", }, }); }; return <button onClick={proceed}>Process</button>; };
- 目标组件(从Context获取函数):
import { useLocation, useNavigate } from "react-router-dom"; import { useTransaction } from './TransactionContext'; const ConfirmationScreen = () => { const location = useLocation(); const navigate = useNavigate(); const { handleCreateTransaction } = useTransaction(); const { redirect } = location.state || {}; const handleConfirm = async () => { await handleCreateTransaction(); navigate(redirect); }; return <button onClick={handleConfirm}>确认交易</button>; };
方案2:传递标识符,目标组件匹配逻辑
如果不想引入全局状态,可以传递一个字符串标识符,目标组件根据标识符匹配对应的函数逻辑。
示例:
- 源组件:
navigate("/confirmationScreen", { state: { actionType: 'createTransaction', redirect: "/wallet", }, });
- 目标组件:
import { useLocation, useNavigate } from "react-router-dom"; const ConfirmationScreen = () => { const location = useLocation(); const navigate = useNavigate(); const { actionType, redirect } = location.state || {}; // 定义所有可能的操作函数 const handleCreateTransaction = async () => { // 创建交易逻辑 }; const handleAction = async () => { switch(actionType) { case 'createTransaction': await handleCreateTransaction(); break; // 可扩展其他操作类型 default: break; } navigate(redirect); }; return <button onClick={handleAction}>确认</button>; };
内容的提问来源于stack exchange,提问作者haider ali
相关产品推荐
相关产品推荐

