React 组件传参 & 路由跳转传参

在 React 开发中,组件传参路由跳转传参 是最核心、最常用的技能,也是新手最容易混淆的知识点。本文会用最通俗的语言、完整可复制的代码,把所有传参方式讲透,覆盖父子组件、兄弟组件、跨级组件、路由页面全场景,看完直接上手开发

一、前置说明

本文基于:

  • React 18+
  • React Router 6+(路由最新版,无兼容问题)
  • 函数式组件 + Hooks(官方推荐写法)

二、React 组件传参(组件间数据通信)

组件传参分为四大场景:

  1. 父组件 → 子组件(最基础)
  2. 子组件 → 父组件
  3. 兄弟组件传参
  4. 跨级组件传参(多层嵌套)

场景 1:父组件 → 子组件传参(props)

核心 :父组件通过自定义属性传值,子组件通过 props 接收。

代码示例
javascript 复制代码
// 父组件 Parent.jsx
import Child from './Child';

function Parent() {
  // 定义要传递的数据
  const userInfo = { name: 'React新手', age: 20 };
  const msg = '来自父组件的问候';

  return (
    <div>
      <h2>我是父组件</h2>
      {/* 直接通过属性传参 */}
      <Child user={userInfo} message={msg} />
    </div>
  );
}
export default Parent;

// 子组件 Child.jsx
// 直接解构 props 接收
function Child({ user, message }) {
  return (
    <div>
      <h3>我是子组件</h3>
      <p>姓名:{user.name}</p>
      <p>年龄:{user.age}</p>
      <p>消息:{message}</p>
    </div>
  );
}
export default Child;

特点

  • 最简单、最常用
  • 只能父传子,不能反向传递

场景 2:子组件 → 父组件传参(回调函数)

核心 :父组件给子组件传一个函数,子组件调用这个函数并把数据当参数传回。

代码示例
javascript 复制代码
// 父组件 Parent.jsx
import { useState } from 'react';
import Child from './Child';

function Parent() {
  const [childData, setChildData] = useState('');

  // 定义接收子组件数据的函数
  const getChildData = (data) => {
    setChildData(data);
  };

  return (
    <div>
      <h2>父组件接收:{childData}</h2>
      {/* 把函数传给子组件 */}
      <Child sendData={getChildData} />
    </div>
  );
}
export default Parent;

// 子组件 Child.jsx
function Child({ sendData }) {
  const handleClick = () => {
    // 调用父组件函数,传参回去
    sendData('我是子组件的数据!');
  };

  return (
    <button onClick={handleClick}>点我给父组件传参</button>
  );
}
export default Child;

场景 3:兄弟组件传参

核心状态提升 → 把数据放到共同的父组件中,通过父组件中转。

流程:兄弟A → 父组件 → 兄弟B

代码示例
javascript 复制代码
// 父组件 Parent.jsx
import { useState } from 'react';
import BrotherA from './BrotherA';
import BrotherB from './BrotherB';

function Parent() {
  const [msg, setMsg] = useState('');
  return (
    <div>
      {/* A 传数据给父组件 */}
      <BrotherA setMsg={setMsg} />
      {/* 父组件把数据传给 B */}
      <BrotherB msg={msg} />
    </div>
  );
}
export default Parent;

// BrotherA.jsx(发送方)
function BrotherA({ setMsg }) {
  return (
    <button onClick={() => setMsg('A传给B的消息')}>
      点我传给兄弟B
    </button>
  );
}

// BrotherB.jsx(接收方)
function BrotherB({ msg }) {
  return <p>B 收到:{msg}</p>;
}

场景 4:跨级组件传参(Context)

当组件嵌套很深(如 父→子→孙→曾孙),用 props 一层层传太麻烦,用 Context 直接跨级传参。

代码示例
javascript 复制代码
// 1. 创建上下文 Context.js
import { createContext } from 'react';
export const MyContext = createContext();

// 2. 顶层组件(祖先)
import { MyContext } from './Context';
import Child from './Child';

function GrandParent() {
  const user = { name: '跨级传参', id: 1001 };
  return (
    // 提供数据
    <MyContext.Provider value={user}>
      <Child />
    </MyContext.Provider>
  );
}

// 3. 底层组件(后代,任意层级)
import { useContext } from 'react';
import { MyContext } from './Context';

function GrandSon() {
  // 直接接收跨级数据
  const user = useContext(MyContext);
  return <p>曾孙收到:{user.name}</p>;
}

适用场景:全局主题、用户信息、多层级共享数据。


三、React Router 6 路由跳转传参

路由传参用于页面之间跳转时传递数据,比如从列表页跳转到详情页,带过去 id、标题等。

React Router 6 有 3 种最常用传参方式

方式 1:路由参数 / 动态路由(推荐)

场景 :传递 id 等必须参数,URL 显示:/detail/123

步骤 1:配置路由
javascript 复制代码
// 路由配置
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import List from './List';
import Detail from './Detail';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/list" element={<List />} />
        {/* 定义动态参数 :id */}
        <Route path="/detail/:id" element={<Detail />} />
      </Routes>
    </BrowserRouter>
  );
}
步骤 2:跳转传参(两种方式)

方式 A:声明式跳转(Link)

javascript 复制代码
import { Link } from 'react-router-dom';

function List() {
  return (
    <Link to="/detail/1001">跳转到详情页(带参数id=1001)</Link>
  );
}

方式 B:编程式导航(useNavigate)

javascript 复制代码
import { useNavigate } from 'react-router-dom';

function List() {
  const navigate = useNavigate();
  return (
    <button onClick={() => navigate('/detail/1001')}>
      编程式跳转传参
    </button>
  );
}
步骤 3:接收参数
javascript 复制代码
import { useParams } from 'react-router-dom';

function Detail() {
  // 获取路由上的 id
  const { id } = useParams();
  return <h2>详情页 ID:{id}</h2>;
}

方式 2:查询参数(?key=value)

场景 :传递可选参数,URL 显示:/search?keyword=react&page=1

跳转传参
javascript 复制代码
// 方式1:Link
<Link to="/search?keyword=react&page=1">搜索页</Link>

// 方式2:编程式
navigate('/search?keyword=react&page=1');
接收参数
javascript 复制代码
import { useSearchParams } from 'react-router-dom';

function Search() {
  const [searchParams] = useSearchParams();
  // 获取参数
  const keyword = searchParams.get('keyword');
  const page = searchParams.get('page');

  return (
    <div>
      <p>关键词:{keyword}</p>
      <p>页码:{page}</p>
    </div>
  );
}

方式 3:隐式传参(state,不显示在 URL)

场景 :传递对象、大量数据,不希望暴露在 URL 上

跳转传参
javascript 复制代码
// 1. Link 方式
<Link 
  to="/detail" 
  state={{ id: 1001, title: '隐式传参', content: '我不显示在URL里' }}
>
  隐式传参跳转
</Link>

// 2. 编程式
navigate('/detail', {
  state: { id: 1001, title: '隐式传参' }
});
接收参数
javascript 复制代码
import { useLocation } from 'react-router-dom';

function Detail() {
  const location = useLocation();
  // 获取隐式参数
  const data = location.state;

  return (
    <div>
      <p>ID:{data.id}</p>
      <p>标题:{data.title}</p>
    </div>
  );
}

四、3 种路由传参对比

传参方式 URL 显示 数据类型 刷新页面 适用场景
动态路由(/:id) 显示 字符串 保留 必选参数(id)
查询参数(?key=val) 显示 字符串 保留 可选参数(分页、搜索)
隐式 state 不显示 任意类型 保留 对象、敏感数据、大量数据

五、总结

  1. 组件传参

    • 父→子:props
    • 子→父:回调函数
    • 兄弟:状态提升(父组件中转)
    • 跨级:Context
  2. 路由传参

    • 必选 id:/detail/:id + useParams
    • 可选参数:?key=val + useSearchParams
    • 对象 / 隐式数据:state + useLocation

六、小建议

  • 简单组件传参:优先用 props / 回调函数
  • 多页面传参:优先用 路由动态参数 + state
  • 全局共享数据:再用 Context / Redux / Zustand

总结

  1. 组件传参 核心:父传子用props、子传父用回调函数 、跨级用Context
  2. 路由传参 核心:动态路由传id、查询参数传可选值、state隐式传对象;
相关推荐
badhope2 小时前
前端已死?前端角色演进的四维技术证据链(2026年实证)
react.js·django·node.js
电商API&Tina2 小时前
唯品会数据采集API接口||电商API数据采集
java·javascript·数据库·python·sql·json
Csvn2 小时前
React 测试入门:Jest + Testing Library 完整指南
前端·react.js
悟空瞎说2 小时前
Flutter面试九阳神功第六层:Platform Channels/三棵树/Key/动画,大白话+实操代码(2026版)
前端
Oneslide2 小时前
手写签名组件实现原理
前端
Lufeidata2 小时前
go语言学习记录-入门阶段
前端·学习·golang
英俊潇洒美少年2 小时前
前端 跨域解决方案
前端
程序员小李白2 小时前
vue题目
前端·javascript·vue.js
okra-2 小时前
什么是接口?
服务器·前端·网络