react 父子通信

本文详细介绍了在React应用中如何通过状态提升实现父子组件间的通信。通过一个实例展示了当用户在摄氏度输入框中输入温度时,如何更新父组件状态,并同步到华氏度输入框,以及子组件如何通过props向父组件传递值进行状态变更。文章涵盖了React组件状态管理、props传递、事件处理和温度转换函数等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

来自react 官网状态提升

 

father
假设在摄氏度输入框中输入温度:
1.父组件中的状态: scale:c , temperature:'' 

this.state = {temperature: '',scale:'c'}


2.摄氏度输入框从父组件中得到 scale:c , temperature:' '。

<Son2 scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange}></Son2>

2-1.父组件传递给子组件一个 onTemperatureChange 方法,方法为:handleCelsiusChange 此方法用来修改父组件中的状态。

handleCelsiusChange(temperature) {
        this.setState({scale: 'c', temperature})

2-2.父组件传递给子组件一个属性 temperature,为: celsius :

celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;

判断 scale 的值是否为 f 如果是则执行 toCelsius 函数,

function toCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9;
  }

如果不是,则直接将 temperature 传递给子组件。
        因为父组件中最初的状态 scale:c 所以这里父组件传递给摄氏度输入框的 temperature 为 父组件的 temperature:' '


3.子组件 

 <input value={temperature} onChange={this.handleChange}/>

3.1 子组件摄氏度输入框的值 value={temperature} 为 value = ' ',
    3.2 当向摄氏度输入框输入值假设输入 100 ,触发 onChange={this.handleChange} 事件。

handleChange(e) {
        this.props.onTemperatureChange(e.target.value)

3.3 handleChange 方法为: this.props.onTemperatureChange(e.target.value) 获取到输入框的值 e.target.value = 100,并将值传递给 onTemperatureChange


4. 父组件中触发 handleCelsiusChange 将 temperature 改为 摄氏度输入框中的值 this.setState({scale: 'c', temperature=100})


5. 此时华氏度输入框从父组件状态中得到的数据将是 :scale: 'c', temperature=100


6. 判断 scale 等于 c 将执行 toFahrenheit 函数。将温度修改为华氏度 212


7.如果在华氏度输入框中输入一个值时,那么将会把这个值通过父组件传递过来的方法 onTemperatureChange 传回这个值给父组件,


8.父组件接收到新的值,修改状态,同时将状态同步到摄氏度输入框。
全部代码:

import React from "react";
import Son1 from './Son1'
import Son2 from './Son2'
// 定义一个函数将 华氏度 转为 摄氏度
function toCelsius(fahrenheit) {
    return (fahrenheit - 32) * 5 / 9;
  }
// 定义一个函数将 摄氏度 转为 华氏度
function toFahrenheit(celsius) {
    return (celsius * 9 / 5) + 32;
  }
function tryConvert(temperature, convert) {
    const input = parseFloat(temperature);
    if (Number.isNaN(input)) {
      return '';
    }
    const output = convert(input);
    const rounded = Math.round(output * 1000) / 1000;
    return rounded.toString();
}
export default class Father extends React.Component {
    constructor(props) {
        super(props)
        this.handleCelsiusChange = this.handleCelsiusChange.bind(this)
        this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this)
        this.state = {temperature: '',scale:'c'}
    }
    // handleChange(e) {
    //     this.setState({temperature: e.target.value})
    // }
    // 创建一个方法,将摄氏度子组件输入框传递过来的 temperature 的值保存在 state 中
    handleCelsiusChange(temperature) {
        this.setState({scale: 'c', temperature});
        console.log(temperature)
    }
    // 创建一个方法,将华氏度子组件输入框传递过来的 temperature 的值保存在 state 中
    handleFahrenheitChange(temperature) {
        this.setState({scale: 'f', temperature});
    }
    
    render() {
        // const temperature = this.state.temperature
        const scale = this.state.scale;
        const temperature = this.state.temperature;
        // 判断 如果为 华氏度 则执行 函数 toCelsius,如果不为华氏度,则直接 摄氏度 等于 temperature
        const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
        const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
        return (
            // <>
            // <input value={temperature} onChange={this.handleChange} />
            // <Son1 num={parseFloat(temperature)}></Son1>
            // </>
            <div>
                <Son2 scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange}></Son2>
                <Son2 scale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange}></Son2>
                <Son1 num={parseFloat(celsius)}></Son1>
            </div>
        )
    }
}

son1

import React from "react";
export default function Son01 (props) {
    if (props.num >= 100) {
        return <p> 水开了 </p>
    }
    return <p> 水没开 </p>
}

son2

import React from "react";
const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
  }
export default class Son2 extends React.Component {
    constructor(props) {
        super(props)
        this.handleChange = this.handleChange.bind(this)
        console.log(this)
        // this.state = {temperature: ''}
    }
    handleChange(e) {
        // this.setState({temperature:e.target.value})
        this.props.onTemperatureChange(e.target.value)
    }
    render() {
        const temperature = this.props.temperature
        const scale = this.props.scale
        return (
            <>
            <p>{scaleNames[scale]}</p>
            <input value={temperature} onChange={this.handleChange}/>
            </>
        )
    }
}

### React父子组件间的通信 #### 使用 Props 进行单向数据流传递 Props 是 React 组件间传递数据的主要机制。父组件可以将任意类型的值作为 prop 传递给子组件,在子组件内部可以直接访问并使用这些 props。 ```jsx // 父组件定义了一个字符串变量并通过prop传递给子组件 function ParentComponent() { const greetingMessage = "Hello, child!"; return ( <div> {/* 将greetingMessage作为名为message的prop传递 */} <ChildComponent message={greetingMessage} /> </div> ); } // 子组件接收来自父级的消息,并显示它 function ChildComponent({ message }) { return <p>{message}</p>; } ``` 此方法体现了 React 的单项数据流动原则,即状态总是自上而下地由父节点流向其后代节点[^1]。 #### 利用回调函数实现双向交互 当需要让子组件影响父组件的状态时,通常会采用回调函数的方式。具体来说就是父组件提供一个处理逻辑(通常是更新自身的某些状态),然后将其作为一个 prop 函数形式传入到子组件中;一旦触发特定事件,比如点击按钮,则执行该回调来通知父组件做出相应改变。 ```jsx class Parent extends React.Component { constructor(props){ super(props); this.state = {childValue: ''}; //绑定handleClick上下文环境至实例本身 this.handleClick=this.handleClick.bind(this); } handleClick(valueFromChild) { console.log(`Received ${valueFromChild}`); this.setState({childValue:valueFromChild}); } render(){ return( <div> <button onClick={()=>this.handleClick('some data')}> Click me to send info back up! </button> {/* 把handleClick方法当作onClick属性赋给了子组件 */} <Child onClick={(val)=>this.handleClick(val)} /> <span>Current Value From Child:{this.state.childValue}</span> </div> ) } } const Child=({onClick})=>{ return(<input type="text" onChange={(e)=>onClick(e.target.value)}/>) } ``` 这种方式允许子组件通过调用父组件提供的函数来回馈信息,实现了更复杂的互动模式[^2]。 #### 应用 Context API 解决多层嵌套问题 对于深层次嵌套结构下的跨层级通讯需求,官方推荐使用 `Context` 来简化这一过程。创建 context 对象后可以在顶层设置 provider 并注入全局共享的数据源,使得子孙树中的任一层次都能方便获取所需资源而不必逐层透传参数。 ```javascript import React, { createContext, useContext } from 'react'; // 创建context对象,默认值可选 const MyContext = createContext(); export function App() { return ( <MyContext.Provider value={{ theme: 'dark', user: 'John Doe' }}> <Toolbar /> </MyContext.Provider> ); } function Toolbar() { return ( <div> <ThemedButton /> </div> ); } function ThemedButton() { const {theme,user}=useContext(MyContext); return ( <button style={{ background: theme === 'light'? '#fff':'#000'}}> Hello,{user} </button> ); } ``` 这种方法特别适合于主题切换、国际化等场景的应用开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值