🧱 用乐高搭页面?React 组件通信原来这么“香”!

30 阅读3分钟

props 到嵌套组件,带你玩转 React 的父子情深(不是)


🎯 开篇暴击:你写的代码,像不像一锅乱炖?

有没有过这样的经历:

  • 父组件的数据想传给子组件?写个函数层层往下塞。
  • 子组件想改父组件的状态?回调函数、状态提升、useContext……脑壳疼。
  • 页面越写越臃肿,最后自己都找不到哪段是干啥的……

别慌!今天我们就来聊聊 React 中最基础、也最容易被忽视的核心概念之一:组件通信
更重要的是——用乐高积木的方式,把页面“拼”出来!


🧩 1. 组件 = 乐高积木,页面 = 你的创意作品

想象一下:你小时候玩乐高,是不是先有一堆小零件(比如轮子、窗户、门),然后咔咔一拼,变成一辆车、一栋房子?

React 里的 组件(Component) 就是这些“乐高积木”:

  • 最小开发单元:一个按钮、一张卡片、一个弹窗,都可以是一个组件。
  • 可复用:写一次,到处用。比如 <Card /> 可以展示用户信息、商品详情、甚至猫猫照片!
  • 可嵌套:组件里还能放组件,就像乐高可以叠着拼。
// App.jsx —— 你是“乐高总指挥”
function App() {
  return (
    <div>
      <Card className="user-card">
        <h2>张三</h2>
        <p>高级前端工程师</p>
        <button>查看详情</button>
      </Card>
    </div>
  )
}

Card 组件呢?它只关心“怎么展示”,不关心“展示谁”。这就是关注点分离的魔法!


📦 2. props:父组件给子组件的“快递包裹”

在 React 世界里,数据流动是单向的:从父到子,像一条单行道。

  • state:组件自己的私有数据(比如用户输入、开关状态)。
  • props:父组件“寄”给子组件的包裹,子组件只能“拆开看”,不能“修改退货”。

举个栗子🌰:

<Greeting name="cww" message="加入字节!!!" showIcon />

这个 <Greeting /> 组件收到三个“包裹”:

  • name:字符串
  • message:字符串
  • showIcon:布尔值(true/false)

子组件只需优雅地“签收”:

function Greeting({ name, message, showIcon }) {
  return (
    <div>
      {showIcon && <span>👋</span>}
      <h1>Hello {name}!</h1>
      <p>{message}</p>
    </div>
  )
}

💡 小贴士props 是只读的!如果你试图在子组件里修改它,React 会默默流泪(然后报错)。


🎁 3. 高级玩法:把“组件”当 props 传!

你以为 props 只能传字符串、数字?太天真了!

React 允许你传递整个组件!这叫 Render Props组件作为 prop

比如我们的 <Modal /> 弹窗:

<Modal
  HeaderComponent={myHeader}
  FooterComponent={myFooter}
>
  <p>这是一个弹窗</p>
  <p>你可以在这里显示任何JSX</p>
</Modal>
  • HeaderComponentFooterComponent 是两个函数组件。
  • 中间的 <p>...</p>children —— React 的“隐藏彩蛋”。

Modal 内部:

const { HeaderComponent, FooterComponent, children } = props;

return (
  <div style={styles.overlay}>
    <div style={styles.modal}>
      <HeaderComponent />   {/* 渲染头部 */}
      <div style={styles.content}>{children}</div>  {/* 渲染中间内容 */}
      <FooterComponent />   {/* 渲染底部 */}
    </div>
  </div>
)

✨ 这招让组件高度可定制!同一个 Modal,可以变出 100 种样式,老板看了直呼“内卷之王”!


🔍 4. 类型安全?PropTypes 来护航!

JavaScript 很自由,但自由过头就容易翻车。比如:

<Greeting name={123} /> // name 居然是数字??

这时候,PropTypes 就像组件的“安检员”:

import PropTypes from 'prop-types';

Greeting.propTypes = {
  name: PropTypes.string.isRequired,     // 必须是字符串,且必传!
  message: PropTypes.string,           // 字符串,可选
  showIcon: PropTypes.bool             // 布尔值
}

// 注意:default 不是这样写的!正确方式是 defaultProps
Greeting.defaultProps = {
  message: "欢迎加入!"
}

⚠️ 虽然现在 TypeScript 更流行,但在纯 JS 项目中,PropTypes 依然是守护神!


💡 5. 思考:为什么 React 要这样设计?

React 强调 单向数据流,看似限制多,实则大智慧:

  • 可预测性:数据从哪来、到哪去,一目了然。
  • 调试友好:出 bug 时,顺着 props 链就能定位。
  • 组件解耦:子组件不依赖父组件的具体实现,只认“接口”(props)。

就像乐高说明书:每一步该拼哪块,清清楚楚。你不会把轮子装到屋顶上(除非你想造飞车🚗)。


🎉 结语:做一名“乐高架构师”

React 的魅力,不在于炫技,而在于用简单规则构建复杂系统

下次写组件时,不妨问自己:

  • 这个组件能不能像乐高一样被复用?
  • 它需要哪些“props 包裹”才能工作?
  • 能不能把 UI 拆得更小、更纯粹?

记住:好的 React 开发者,不是写代码最多的人,而是写组件最“懒”的人——因为他们的组件,早就被复用了 100 次!