React State与生命周期

一、React State介绍

React将组件看成是一个状态机(State Machines),通过其内部定义的状态State与生命周期Lifecycle实现与用户的交互,维持组建的不同状态。

React为什么定义State概念?
只需要通过更新React组件的状态State,就可以实现重新渲染用户界面的操作,这样就不需要操作DOM了。

state的创建:

class MyComponent extends React.Component {
	constructor(props) {  //构造函数
	    super(props);  //必须是构造函数的第一句
	    this.state = { // 状态机
	        value:'Hello'
	    }
	}
}

什么时候使用State?
由于React对props的严格保护机制,一旦给定值,在组件中是不允许改变的,但是很多应用场合中,组件的内容需要根据数据的刷新而刷新,这个时候就需要用到React提供的State,即状态机。

二、React组件的生命周期

每个组件都包含“生命周期法”,可以通过重写这些方法,实现在运行过程中特定的阶段执行这些方法。

(1)挂载

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

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

构造函数:constructor(props): 在React组件挂载之前,会调用它的构造函数。

构造函数的使用:

  • 通过给this.state赋值对象来初始化内部state
  • 为事件处理函数绑定实例

注:如果不初始化state或不进行方法绑定,则不需要为React组件实现构造函数。在为React.Component子类实现构造函数时,应在其他语句前调用super(props),否则this.props在构造函数中可能会出现未定义的bug。

在constructor()函数中不要调用setState()方法。如果组件需要使用内部state,请直接在构造函数中为this.state赋值初始化state。

constructor(props){
	super(props);
	//不要在这里调用this.setState()
	this.state={counter:0};
	this.handleClick=this.handleClick.bind(this);
}

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

当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一:

  • React 元素。 通常通过 JSX 创建。例如,< div /> 会被 React 渲染为 DOM 节点,< MyComponent />会被 React 渲染为自定义组件,无论是 < div /> 还是 < MyComponent /> 均为 React 元素。
  • 数组或fragments。 使得 render 方法可以返回多个元素。
  • Portals。 可以渲染子节点到不同的 DOM 子树中。
  • 字符串或数值类型。 它们在 DOM 中会被渲染为文本节点。
  • 布尔类型或 null。 什么都不渲染。

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

函数内部适合的事件:依赖于DOM节点的初始化,通过网络请求数据,添加订阅。

注:如果添加了订阅,请不要忘记在 componentWillUnmount() 里取消订阅。

可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。通常,你应该在 constructor() 中初始化 state。如果你的渲染依赖于DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理

(2)更新

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

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • reander()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot): 会在更新后会被立即调用,首次渲染不会执行此方法。

当组件更新后,可以在此处对 DOM 进行操作。

componentDidUpdate(prevProps){
	//典型用法,不要忘记比较props:
	if(this.props.userID!==prevProps.userID){
		this.fetchData(this.props.userID);
	}
}

也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。

(3)卸载

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

componentWillUnmount():
该方法会在组件卸载及销毁之前直接使用,在此方法中执行必要的清理操作,例如清除timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。

注:componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值