You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-router-dom 6.4.2:生产环境useNavigate传函数返回null问题

解决React Router 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实现

  1. 创建交易上下文:
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);
  1. 源组件(仅传递非函数数据):
import { useNavigate } from "react-router-dom";

const SourceComponent = () => {
  const navigate = useNavigate();
  
  const proceed = () => {
    navigate("/confirmationScreen", {
      state: {
        redirect: "/wallet",
      },
    });
  };

  return <button onClick={proceed}>Process</button>;
};
  1. 目标组件(从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:传递标识符,目标组件匹配逻辑

如果不想引入全局状态,可以传递一个字符串标识符,目标组件根据标识符匹配对应的函数逻辑。

示例:

  1. 源组件:
navigate("/confirmationScreen", {
  state: {
    actionType: 'createTransaction',
    redirect: "/wallet",
  },
});
  1. 目标组件:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:50:39