react学习之函数式组件-子传父

我爱海鲸 2026-05-02 15:06:40 暂无标签

简介vite

App.jsx:

import { useEffect, useState } from 'react'
import ChildActions from './components/ChildActions.jsx'
import './App.css'

export default function App() {
  const [count, setCount] = useState(0)
  const [fromChild, setFromChild] = useState('(还没有)')

  const handleStep = (delta) => {
    setCount((c) => c + delta)
  }

  const handleSend = (text) => {
    setFromChild(text.trim() === '' ? '(空字符串)' : text)
  }

  useEffect(() => {
    document.title = '子传父 · 回调'
  }, [])

  return (
    <main className="app">
      <h1>子组件 → 父组件(回调 props)</h1>
      <p className="hint">
        数据存在<strong>父组件</strong>的 <code>useState</code> 里。父组件把{' '}
        <code>handleStep</code>、<code>handleSend</code> 通过 props 交给子组件;子组件在点击时调用它们,相当于把孩子里的信息交给了父组件。
      </p>

      <p className="count">
        父 state · 计数:<strong>{count}</strong>
      </p>
      <p className="count">
        父 state · 子传来的话:<strong>{fromChild}</strong>
      </p>

      <ChildActions onStep={handleStep} onSend={handleSend} />
    </main>
  )
}

ChildActions.jsx:

import { useState } from 'react'

export default function ChildActions({ onStep, onSend }) {
  const [draft, setDraft] = useState('')

  return (
    <div className="child">
      <p className="child__label">子组件:通过调用父传入的函数,把数据「传上去」</p>
      <div className="actions">
        <button type="button" onClick={() => onStep(5)}>
          子:+5
        </button>
        <button type="button" onClick={() => onStep(-2)}>
          子:−2
        </button>
      </div>
      <div className="child__row">
        <input
          className="child__input"
          type="text"
          placeholder="输入一句话"
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
        />
        <button
          type="button"
          onClick={() => {
            onSend(draft)
            setDraft('')
          }}
        >
          子:把输入传给父
        </button>
      </div>
    </div>
  )
}

App.css:

.app {
  max-width: 30rem;
  margin: 2.5rem auto;
  padding: 0 1.25rem;
  font-family: system-ui, sans-serif;
  line-height: 1.55;
  color: #1a1a1a;
}

.app > h1 {
  font-size: 1.25rem;
  font-weight: 650;
  margin: 0 0 0.65rem;
}

.hint {
  margin: 0 0 1.1rem;
  font-size: 0.9rem;
  color: #555;
}

.hint code {
  font-size: 0.85em;
  background: #f3f4f6;
  padding: 0.08em 0.35em;
  border-radius: 4px;
}

.count {
  margin: 0 0 0.5rem;
  font-size: 0.98rem;
}

.count:last-of-type {
  margin-bottom: 1.15rem;
}

.child {
  border: 1px solid #e5e7eb;
  border-radius: 10px;
  padding: 1rem 1.1rem;
  background: #fafafa;
}

.child__label {
  margin: 0 0 0.85rem;
  font-size: 0.88rem;
  color: #444;
}

.child__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.85rem;
  align-items: center;
}

.child__input {
  flex: 1;
  min-width: 10rem;
  padding: 0.4rem 0.55rem;
  border: 1px solid #ccc;
  border-radius: 6px;
  font-size: 0.95rem;
  box-sizing: border-box;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.actions button,
.child__row button {
  padding: 0.45rem 0.9rem;
  font-size: 0.92rem;
  cursor: pointer;
  border: 1px solid #ccc;
  border-radius: 6px;
  background: #fff;
}

.actions button:hover,
.child__row button:hover {
  background: #f9fafb;
}

相关知识点总结:

通信方向:子组件 → 父组件,通过回调函数实现

实现原理:父组件定义事件处理函数,通过 props 传递给子组件;子组件触发时调用该函数

数据传递:子调用函数时可传入参数,将数据 / 消息传给父组件

状态管理:数据 / 状态始终保存在父组件,子组件只负责触发更新

核心语法:父传 onXxx 回调 props,子通过 props.onXxx(参数) 调用

作用:实现子组件通知父组件、子向父传值、子触发父状态更新

你好:我的2025