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

React Router传递函数类型Props遇undefined问题求助

嘿,我完全懂你碰到的这个坑——React Router的Link组件通过URL路径传递函数类型的props根本走不通,毕竟URL只能存能序列化的数据(像字符串、数字这类),函数是没法被转成路径字符串的,这就是为啥你的decreaseIndexProject在子组件里变成undefined的原因。下面给你两个靠谱的解决方案:

问题根源分析

你之前用的<Link to={'/Content/' + this.props.index + '/' + this.props.decreaseIndexProject}>本质是把函数直接拼进了URL路径里,但函数是引用类型,会被转成[object Function]这种无效的路径片段,React Router自然没法把它解析成有效的prop传递给子组件,所以子组件拿到的就是undefined。

解决方案1:用Link的state属性传递函数

React Router的Link组件支持传入一个对象作为to属性,其中的state字段可以用来传递任意数据(包括函数),因为这部分数据是存在内存里的,不会被序列化到URL中。

改写你的Link组件:

<Link 
  to={{
    pathname: `/Content/${this.props.index}`,
    state: { decreaseIndexProject: this.props.decreaseIndexProject }
  }}
>
  Page n°1
</Link>

子组件获取函数:

根据你的子组件是函数组件还是类组件,有两种写法:

  • 函数组件(用useLocation钩子):
import { useLocation } from 'react-router-dom';

function Content() {
  const location = useLocation();
  // 加个空对象兜底,避免state不存在时报错
  const { decreaseIndexProject } = location.state || {};

  const handleDecrease = () => {
    // 调用前先判断函数是否存在,防止报错
    if (decreaseIndexProject) {
      decreaseIndexProject();
    }
  };

  return <button onClick={handleDecrease}>Decrease Index</button>;
}
  • 类组件(通过props.location):
import React from 'react';

class Content extends React.Component {
  handleDecrease = () => {
    const { decreaseIndexProject } = this.props.location.state || {};
    if (decreaseIndexProject) {
      decreaseIndexProject();
    }
  };

  render() {
    return <button onClick={this.handleDecrease}>Decrease Index</button>;
  }
}

注意点:

如果用户直接刷新子组件页面,state里的数据会丢失(因为它存储在内存中,不是URL的一部分)。如果你的场景需要刷新后依然能获取到函数,建议用下面的方案。

解决方案2:用React Context或全局状态管理

如果这个函数需要在多个组件间共享,或者要避免刷新丢失的问题,可以用React Context或者像Redux、Zustand这类全局状态管理工具来传递函数。

用React Context的示例:

  1. 创建Context:
import React, { createContext, useContext } from 'react';

// 创建Context,默认值可以设为空对象
const ProjectContext = createContext({});

// 定义Provider组件,用来传递函数
export function ProjectProvider({ children, decreaseIndexProject }) {
  return (
    <ProjectContext.Provider value={{ decreaseIndexProject }}>
      {children}
    </ProjectContext.Provider>
  );
}

// 自定义钩子,方便子组件获取Context
export function useProjectContext() {
  return useContext(ProjectContext);
}
  1. 在父组件外层包裹Provider:
import { ProjectProvider } from './ProjectContext';

// 假设这是你的父组件
class ParentComponent extends React.Component {
  decreaseIndexProject = () => {
    // 你的函数逻辑
    console.log('Decreasing index...');
  };

  render() {
    return (
      <ProjectProvider decreaseIndexProject={this.decreaseIndexProject}>
        <Link to={`/Content/${this.props.index}`}>Page n°1</Link>
      </ProjectProvider>
    );
  }
}
  1. 子组件从Context获取函数:
import { useProjectContext } from './ProjectContext';

function Content() {
  const { decreaseIndexProject } = useProjectContext();

  return <button onClick={decreaseIndexProject}>Decrease Index</button>;
}

这个方案的好处是,只要ProjectProvider在组件树中存在,子组件就能随时获取到函数,即使刷新页面也不会丢失(前提是函数的定义在Provider的上层,且页面刷新后Provider能重新渲染)。

额外注意:PropTypes配置

如果用方案1,子组件的PropTypes可以这样配置:

import PropTypes from 'prop-types';

Content.propTypes = {
  location: PropTypes.shape({
    state: PropTypes.shape({
      decreaseIndexProject: PropTypes.func
    })
  })
};

如果用方案2,子组件不需要配置这个PropTypes,因为函数是从Context获取的。

内容的提问来源于stack exchange,提问作者Guillaume

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 04:17:27