极品-------React的组件通信,生命周期,受控组件,与非受控组件

本文介绍了React中组件间的四种通信方式:父传子、子传父、兄弟组件间通信及跨组件通信,并探讨了受控与非受控组件的区别,最后概述了React组件的生命周期。

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

React中的主要的组件通信有
一.父传子
二.子传父
三.兄弟相传

一.父传子

父组件传递数据给子组件
1.父组件中引入子组件

import Family from "./family";

2.在父组件中使用子组件

  <Family/>

3.父组件提供要传递的state数据

  state = {
    Lastname:"火娃",
  }

4.给子组件标签添加属性.值为state中的数据

  <Family name={this.state.Lastname}/>

5.子组件中通过props接受父组件中传递的数据

 <li>{this.props.name}</li>

父组件

class App extends Component{
  state = {
    hEight:174,
    tex:'',
    Lastname:"火娃",
    shu:0
  }
  render(){
    return (<div>
        <Family name={this.state.Lastname}/>
    </div>)
  }
}

子组件

class Family extends React.Component{
    render(){
      return  (<div>
            <ul>  
                <li>{this.props.name}</li>
            </ul>
        </div>)
    }
};
ReactDOM.render(<Family/>,
document.querySelector('#root'))
export default Family

二.子传父

子传父,父组件提供一个方法,把方法传给子组件,子组件调用传参,这是回调函数
1.提供方法

 Child = props =>{
    return(
      <div>
        <p>{props.name}</p>
      </div>
    )
  }

2.传给子组件

  <Family  getMsg={this.Child} }/> 

3.子组件调用

 dianclick=()=>{
        this.props.getMsg(this.state.msg)
    }

4.传入子组件的数据

  state={
        msg:'水娃'
    }
    dianclick=()=>{
        this.props.getMsg(this.state.msg)
    }

父组件

class App extends Component{
  state = {
    hEight:174,
    tex:'',
    Lastname:"火娃",
    shu:0
  }
  getChild=(data)=>{
    console.log(data)
  }
  Child = props =>{
    return(
      <div>
        <p>{props.name}</p>
      </div>
    )
  }
  render(){
    // let {hEight} = this.state
    return (<div>
        <Family  getMsg={this.Child} }/> 
  }
};

子组件

class Family extends React.Component{
    state={
        msg:'水娃'
    }
    dianclick=()=>{
        this.props.getMsg(this.state.msg)
    }
    render(){
      return  (<div>
            <ul>
                <li>{this.props.name}</li>
                <li>{this.props.shu}</li>
            </ul>
        </div>)
    }
};
ReactDOM.render(<Family/>,
document.querySelector('#root'))
export default Family

三.兄弟组件传参

React组件通信中兄弟传参需要媒介,他们共同的父组件该变父组件中的而改变子组件的
1.在父组件中定义方法

  onIncrement = ()=>{
    this.setState({
      shu:this.state.shu+1
    })
  }

2.在父组件中定义属性

 state = {
    shu:0
  }

3.传给子组件

 <Family  shu={this.state.shu}/>
 <Parent onIncrement={this.onIncrement}/>

4.子组件中使用

第一个子组件
  <li>{this.props.shu}</li>
第二个子组件 
 <button onClick={()=>this.props.onIncrement()}>+1</button>

父组件

class App extends Component{
  state = {
    shu:0
  }
  getChild=(data)=>{
    console.log(data)
  }
  onIncrement = ()=>{
    this.setState({
      shu:this.state.shu+1
    })
  }
  render(){
    // let {hEight} = this.state
    return (<div>
        <Family  shu={this.state.shu}/>
        <Parent onIncrement={this.onIncrement}/>
    </div>)
  }
};

第一个子组件

import React from "react";
import ReactDOM from "react-dom";

class Family extends React.Component{
    state={
        msg:'水娃'
    }
    // Child = props=>{
    //     return (
    //         <div>
    //             <p>{props.Lastname}</p>
    //         </div>
    //     )
    // }
    dianclick=()=>{
        this.props.getMsg(this.state.msg)
    }
    render(){
      return  (<div>
           {/* <button onClick={this.Child()}>父传子</button> */}
            <ul>
                <li>one</li>
                <li>two</li>
                <li>three</li>
                <li>{this.props.name}</li>
                <li>{this.props.shu}</li>
            </ul>
            <button onClick={this.dianclick}>点击葫芦娃</button>
        </div>)
    }
};
ReactDOM.render(<Family/>,
document.querySelector('#root'))
export default Family

第二个子组件

import React from "react"
import Boy from "./boy"
class Parent extends React.Component{
    render(){
        return(
            <div>
                <Boy />
                <p>我是二组件</p>
                <button onClick={()=>this.props.onIncrement()}>+1</button>
            </div>
        )
    }
}
export default Parent

跨组件传参

const {Provider,Consumer} = React.createContext()
class App extends Component{
  render(){
    return (<div> 
    	//创建
        <Provider value="孙子嘿嘿">
        <Parent onIncrement={this.onIncrement}/>
        </Provider>
    </div>)
  }
};
//消耗
 <Consumer>
         {data => <p>我是孙子{data}</p>}
 </Consumer>

五.受控组件与非受控组件

解释:
在 HTML 中,表单元素(如input、 textarea 和 select)通常自己维护 state,并根据用户输入进行更新。而在 React 中,可变状态(mutable state)通常保存在组件的 state 属性中,并且只能通过使用 setState()来更新。
可以把两者结合起来,使 React 的 state 成为“唯一数据源”。渲染表单的 React 组件还控制着用户输入过程中表单发生的操作。被 React 以这种方式控制取值的表单输入元素就叫做“受控组件”。
见解:
每当输入框的输入内容发生变化时,都会被写入到组件的state中,这种组件在React中被理解为受控组件。
受控组件的值,始终是由React的state驱动的。
这种组件的数据是由React组件进行管理的,所以在大多数情况下,官方推荐使用受控组件。

受控组件

import React, { Component, Fragment } from 'react'
export default class Demohooks extends Component {
  constructor(props) {
    super(props);
    this.state = {
      controllValue: 0,
    }
  }
  onChangeInput = (e) => {
    this.setState({
      controllValue: e.target.value
    })
  }
  render() {
    return (
      <Fragment>
        <h1>受控组件</h1>
        <div>{this.state.controllValue}</div>
        用户名:<input value={null} onChange={this.onChangeInput} />
      </Fragment>
    )
  }
}

非受控组件
官网:
要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以使用 ref来从 DOM 节点中获取表单数据。
因为非受控组件将真实数据储存在 DOM 节点中,所以在使用非受控组件时,有时候反而更容易同时集成 React 和非 React 代码。如果你不介意代码美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件。

总的来说就是操作DOM节点,所以官方推荐受控组件
非受控组件

import React, { Component } from 'react'

export default class Demohooks extends Component {
  onSubmit = (event) => {
    event.preventDefault();
    const { inputName, password } = this;
    console.log(inputName.value)
    console.log(password.value)
  }
  render() {
    return (
      <div>
        <form onSubmit={this.onSubmit}>
          用户名:<input ref={c => this.inputName = c} /> <br />
          密码:<input ref={c => this.password = c} /> <br />
          <button>登录</button>
        </form>
      </div>
    )
  }
}

React生命周期

生命周期的方法有:
constructor()
constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。
注意:只要使用了constructor()就必须写super(),否则会导致this指向错误。

componentWillMount()
componentWillMount()一般用的比较少,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。

componentDidMount()
组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染

componentWillUnmount ()
在此处完成组件的卸载和数据的销毁。

componentWillReceiveProps (nextProps)
在接受父组件改变后的props需要重新渲染组件时用到的比较多
接受一个参数nextProps
通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件

shouldComponentUpdate(nextProps,nextState)
主要用于性能优化(部分更新)
唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断
componentWillUpdate (nextProps,nextState)
shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,这里同样可以拿到nextProps和nextState。

componentDidUpdate(prevProps,prevState)
组件更新完毕后,react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state。

render()
render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

getDerivedStateFromProps(nextProps, prevState)
代替componentWillReceiveProps()。
老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数
getSnapshotBeforeUpdate(prevProps, prevState)
代替componentWillUpdate。
常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。
这两者的区别在于:

在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在
componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。
getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。
此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值