IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 极品-------React的组件通信生命周期受控组件与非受控组件 -> 正文阅读

[JavaScript知识库]极品-------React的组件通信生命周期受控组件与非受控组件

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()。
在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 13:24:52  更:2021-07-28 13:24:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/26 22:10:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码