极品-------React的组件通信,生命周期,受控组件,与非受控组件
Posted 哈比老乌龟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极品-------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()。
以上是关于极品-------React的组件通信,生命周期,受控组件,与非受控组件的主要内容,如果未能解决你的问题,请参考以下文章
极品-------React的组件通信,生命周期,受控组件,与非受控组件