React基础语法的学习---6.各种关系组件传值, 复用, 生命周期

文章详细介绍了React中父组件如何通过ref直接操作子组件,包括改变子组件状态和触发子组件方法。同时阐述了子组件如何通过回调函数来操作父组件的状态。此外,还讨论了兄弟组件间通过父组件中转实现值的传递。最后提到了组件的生命周期,包括挂载、更新和卸载阶段的关键方法及其用途。
摘要由CSDN通过智能技术生成

父操作子

   思路:获取子组件节点直接进行操作

   父组件

//父组件
import React,{ Component,creatRef} from 'react'
import Son from './son'

export default class Father extends Component{
  constructor(props) {
    super()
    this.changeSon = creatRef()
  }

  //父组件的函数
  changeURL = () => {
    //父组件通过ref拿可以访问子组件内的所有属性和方法并对其进行操作
    this.changeSon.current.setState({ URL:'./src'})  //改变子组件url
    
    this.changeSon.current.changeSize()   //触发子组件的过度函数
  }

  render(){
    return (
      <>
        <button onclick={()=>this.changeURL()}></button>
        <Son ref={this.changeSon} />
      </>
    )
  }
}

  操作子组件

import React,{ Component,creatRef} from 'react'
export default class Son extends Component{
  constructor(props) {
    super()
    this.state={
      URL:'./img'
    }
    this.son = creatRef()
  }

  //子组件函数
  changeSize = () => {
  
    //图片放大2倍
    this.son.current.transform='scale(2)'
    //动画过渡 1s
    this.son.current.transition='all 1s'
  }

  render(){
    return (
      <div>
        <img 
         ref={this.son}
         src={this.state.URL}
         onClick={()=>this.changeSize()} /> 
        
      </div>
    )
  }
}

子操作父

  思路:通过回调函数对父组件的状态更新

  父组件

//父组件
import React,{ Component } from 'react'
import Son from './son'

export default class Father extends Component{
  constructor(props) {
    super()
    this.state ={
      type:false
    }
  }
  //父组件的函数传递到子组件 子调用后赋值
  callBackValue = e => {
    this.setState({type:e})
  }
 

  render(){
    const { type } = this.state
    return (
      <>
        {/* 根据子的布尔,父展示不同的值 */}
        {type?'今天熬夜吧':'算了还是睡觉吧'}
        <Son 
          type={type}
          //bind指定作用域
          callBackValue={this.callBackValue.bind(this)}
        />
      </>
    )
  }
}

子组件

//父组件
import React,{ Component } from 'react'
 

export default class Son extends Component{
  constructor(props) {
    super()
    //子组件的布尔值
    this.state ={
      type:false
    }
  }
  
  //钩子函数,类似于vue的 created,挂载前操作
  componentDidMount(){
    //把父组件传递的 type 解构出来
    const { type } = this.props
    //赋值给子组件的type
    this.setState({ type })
  }
 

  callBakcFahter = () => {
    const { type } = this.state
    //父组件传递的回调函数从props内解构
    const { callBackValue } = this.props
    let newCheckBoolean = !type
    //解构出来子的type 赋值变量,然后通过setState 对type重新赋值取反,并将新得值通过回调函数更新到父组件内
    this.setState({
      type:newCheckBoolean
    })
    //回调传递
    callBackValue(newCheckBoolean)

  }

  render(){
    const { type } = this.state
    return (
      <>
        子组件
        <input type='checkbox'   checked={type}  onChange={ () =>this.callBakcFahter() }/> 
      </>
    )
  }
}

兄弟传值

  思路:通过父组件中转,兄弟组件内,将公用的值进行更新后传递到父组件,再通过生命周期getDerivedStateFromProps进行同步,达到兄弟传值的效果

//父组件
import React,{ Component } from 'react'
export default class Father extends Component{
  constructor(props) {
    super()
    this.state ={
      showArr:[1,2,3,4,5  ]
    }
  } 
  upDateArr = v => {
    let newV = v.length?v.split:['暂无数据']
    this.setState({showArr:newV })
  }

  render(){
    const { showArr } = this.state
    return (
      <>
        {/* 一号兄弟 */}
        <SonOne  upDateArr={this.upDateArr.bind(this)} / >


        {/* 二号兄弟 */}
        <SonTwo  showArr={showArr} / >

      </>
    )
  }
}

一号兄弟修改值

//一号兄弟组件
import React,{ Component } from 'react'
export default class SonOne extends Component{
  constructor(props) {
    super()
    this.state ={
      showArr :[{key:'123'},{key:'456'},{key:'789'}],
    }
  } 
  upDateArr = v => {
    this.setState({showArr:v})
  }

  render(){
    const { showArr } = this.state
    return (
      <>
       <table>
        <thead>
          <tr>
             <th>当前数组</th>
             <th>操作</th>
          </tr>
        </thead>
        <tbody>
          {showArr && showArr.map(item=>{
            return(
              <tr key={item.key}>
                <td> {item.key} </td>
                <td>  
                  <button onClick={()=> this.props.upDateArr(item.key)}>
                    展示当前数据  
                  </button>  
                </td>
              </tr>
            )
          })}
        </tbody>
       </table>

      </>
    )
  }
}

 二号兄弟同步更新值

//父组件
import React,{ Component } from 'react'
export default class SonOne extends Component{
  constructor(props) {
    super()
    this.state ={
      showArr:[],
    }
  } 
 
  // 加载更新state
  componentDidMount(){
    //解构父传递的值更新到自己
    const { showArr } = this.props 
    this.setState({showArr})
  }

  //生命周期,会检测自己的状态与父的状态  nextProps==父  prevState==自己
  static getDerivedStateFromProps(nextProps,prevState){
    //判断父的值与当前 组件值是否相等,不等则进行更新
    if(nextProps.showArr !== prevState.showArr){
      return{
        showArr:nextProps.showArr
      }
    }
    return null
  }
   
  //更新后调用的生命周期  当前的props 和当前的state
  componentDidUpdate(prevProps,prevState){
    if(prevProps.showArr !== this.props.showArr){
      alert("同步完成")
    }
  }

  

  render(){
    const { showArr } = this.state
    return (
      <>
      
        兄弟二号
        <span> 
          { showArr }
        </span>

      </>
    )
  }
}

组合实现代码之间组件复用

有些组件我们无法提前知晓他们子组件内的具体内容,建议这些组件使用一个特殊的children props来将他们的子组件传递到渲染的结果中,当然我们也可以通过自行约定来使用,而不用通过children。

  使用children

function Test(props){
    return(
      <div>
        {props.children}
      </div>
    )
  }



  function hello(){
    return (
      <div>
        <Test>
          <h1>你好啊</h1>
          <button>666</button>
        </Test>
        <Test>
          <h1>999</h1>
          <button>111</button>
        </Test>
      </div>
    )
  }

  自行约定

  //组件1
  function IMG(){
    return(
      <img src={URL}/> 
  }

  //组件2
  function Title(){
    return(
      <div>标题:{title}</div>
    )
  }


  //预定组件
  export default function Test (props){
    return(
      <div>
        {props.top}
        {props.bottom}
      </div>
    )
  }

  //使用约定
 render(){
  <div>
    <Test  top={<IMG/>}  bottom={<Title title='标题1'>}  /> 
  </div>
 }

生命周期

生命周期指的是挂载,更新和销毁三个阶段,三个阶段内可以插入预设的函数来修改部分逻辑和操作dom达到预期效果。

     生命周期三个状态:

    1.Mounting(挂载): 已经插入真实DOM

    2.Updating(更新): 正在被重新渲染

    3.Unmounting(卸载):已经移除真实DOM

挂载:

当组件实例被创建并插入 DOM 中时,其生命周期调用顺序:

如果是父子组件,则先进行 父的render ---> 子render  ---> 子cpdm---> 父cpdm的顺序


    1.constructor():在React组件挂載之前,会调用它的构造函数(在react组件挂在前,会调用它的构造函数,在为React.component子类实现构造函数时,应在其他语句之前调用红super(props),否则在this.props构造函数中可能会出现未定义的BUG)


    2. static  getDerivedstateFromProps():在调用render 方法之前调用,并旦在初始挂载及后续更新时都会被调用,常用于兄弟组件更新时。
   


    3. render():render() 方法是 class 组件中唯一必须实现的方法。

    render(函数应该为纯函数,这意味着在不修政组件state 的情况下                                                    每次调用时都返回相同的结果,并且它不会直接与浏览器交互。
    如需与浏览器进行交互,请在componentDidmount(或其他生命周期方法中执行你的操作)

    4.componentDidvount():在组件挂载后(插入DOM 树中)立即调用。

    如果cpd()内调用的函数内有this.setState()操作,那么会重新调用render()
 

更新:

每当组件的state 或 props 发生变化时,组件就会更新。
当组件的 props 或 state 发生变化时会触发更新。组件更新的生命周期调用顺序如下:


    1.getperivedstateFromProps():在调用render方法之前调用,并且在初始挂载及后续更新时都会被调用。根据 shouldcomponentUpdate()的返回值,判断 React 组件的输出是否受当前 state
或 props 更改的影响。

      componentDidupdate()不可以直接使用,会导致死循环


    2.shouldcomponentupdate();当 props 或state 发生变化时,shouidcomponentUpdate() 会在渲染执行之前被调用。如果shouldcomponentupdate返回了false,则不会触发render调用和componentDidupdate()
    3.render():render()方法是class 组件中唯一必须实现的方法。


    4.getsnapshotBeforeupdate():在最近一次渲染输出(提交到 DOM 节点)之前调用。


    5.componentDidupdate():state状态发生改变后调用。

卸载:

当组件从DOM中移除时会调用如下方法:

      componentWillUnmount():在组件卸载及销毁之前调用

     //常用的清除定时器操作

  constructor(props) {
    super()
    this.timer = null
  } 
 
  componentDidMount(){
    this.timer = setInterval(()=>{
      console.log( new Date().getTime())
    },100)
  }

  componentWillUnmount(){
    clearInterval( this.timer )
  }

错误处理:

  当渲染过程,生命周期,子组件的构造函数抛出错误时,会调用如下方法:

 1. static getDeriveStateFromError()

 2.componentDidCatch()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值