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隐式传对象;
相关推荐
canonical_entropy7 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
东方小月7 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构
我叫黑大帅7 小时前
为什么需要 @types/react?解决“无法找到模块 react 的声明文件”报错
前端·javascript·面试
之歆7 小时前
DAY_21JavaScript 深度解析:数组(Array)与函数(Function)(一)
前端·javascript
XinZong8 小时前
【AI社交】基于OpenClaw自研轻量化AI社交平台实战
前端
Le_ee8 小时前
ctfweb:php/php短标签/.haccess+图片马/XXE
开发语言·前端·php
爱上好庆祝8 小时前
学习js的第七天(wed APIs的开始)
前端·javascript·css·学习·html·css3
KaMeidebaby9 小时前
卡梅德生物技术快报|冻干工艺开发:注射用心肌肽全流程参数优化与工程化方案
前端·其他·百度·新浪微博
ooseabiscuit9 小时前
Laravel6.x核心优化与特性全解析
android·开发语言·javascript
哆啦A梦158810 小时前
20, Springboot3+vue3实现前台轮播图和详情页的设计
javascript·数据库·spring boot·mybatis·vue3