子组件如何在不监听生命周期方法的情况下从父组件接收 props?

Posted

技术标签:

【中文标题】子组件如何在不监听生命周期方法的情况下从父组件接收 props?【英文标题】:How does the child component receive props from the parent component without listening for the lifecycle method? 【发布时间】:2019-07-09 07:02:38 【问题描述】:

要更新子组件中的props对象,通常使用生命周期方法ComponentWillReceiveProps。但我意识到子组件的props 可以在不监听ComponentWillReceiveProps 的情况下更新。

例如,在下面名为App的组件中,子组件Comp可以在不监听生命周期方法ComponentWillReceiveProps的情况下接收props

主要的App组件:

import React from 'react';
import ReactDOM from 'react-dom';
import Comp from "./comp";

class App extends React.Component 

  constructor(props) 
    super(props);
    this.state = 
      counter: 0
    

    this.incrementCounter = this.incrementCounter.bind(this);
  

  componentDidMount() 
    this.setState(
      counter: 100
    )
  

  incrementCounter() 
    this.setState(
      counter: this.state.counter + 1
    )
  

  render() 
    return (
      <div>
              <button onClick=this.incrementCounter>Increment</button>
              <br />
              <br />
              <Comp counter=this.state.counter/>
      </div>
    )
  


ReactDOM.render(<App />, document.getElementById('container'));

和子Comp组件:

import React from 'react';

export class Comp extends React.Component 

  constructor(props) 
    super(props);
    this.state = 
  

  componentDidUpdate(prevProps, prevState) 
    console.log("prev props ", prevProps);
    console.log("prev state", prevState)
  

  render() 
    return <span>Props received: JSON.stringify(this.props)</span>
  

这也是我准备的上述代码的工作演示

您会看到子组件Comp 接收到属性counter 而不监听任何生命周期方法。

这是什么意思?我错过了什么吗?

【问题讨论】:

我认为子组件正在重新渲染。这就是您获得更新道具的原因。当 App 的状态发生变化时,它会再次渲染,使子组件也重新渲染。当不重新渲染父组件时,生命周期方法会派上用场。我们只希望我们的子组件重新渲染。 @OsamaKhalid 我不明白。能否举个例子,父组件没有被重新渲染,而子组件被重新渲染。 对不起,我在上面的评论中犯了一个错误。 ComponentWillReceiveprops 不控制子组件的重新渲染。当父组件的状态发生变化时,子组件总是会重新渲染。这种方法的用途是让我们为子组件做出逻辑决策,因为它具有先前的 props 和 nextprops,因此我们可以在调用子函数的渲染之前使用它们为子组件设置一些数据/状态. 【参考方案1】:

componentWillReceiveProps() 是一种已弃用的生命周期方法,它在组件即将接收新道具时触发。 但是,它无法控制组件是否实际接收到这些道具。

https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops

无论componentWillReceiveProps()是否被执行,组件都会从父级接收更新的props。

import React from 'react';

export class Comp extends React.Component 

  constructor(props) 
    super(props);
    this.state = 
  

  render() 
    console.log(this.props.counter) //still gets printed with new props data
    return <span>Props received: JSON.stringify(this.props)</span>
  

请注意,props 是严格从 Parent 到 Child 组件传递的。

当通过状态更改重新渲染父组件时,它也会重新渲染子组件并传递更新的道具。现在,子组件可以访问这些新道具,并且它们会经历事件的 React 生命周期。

componentDidUpdate()componentWillReceiveProps() 等事件允许您执行一些额外的逻辑,但组件接收道具或重新渲染不需要它们。无论使用情况如何,组件都会重新渲染。

此外,子组件可以像任何基于类的组件一样通过内部状态更新来更新自身。

【讨论】:

【参考方案2】:

每次您在父节点/组件上执行 setState 时,它​​都会使用最新的道具重新渲染所有子组件。所以基本上每当父组件重新渲染时,该节点的所有子组件都会重新渲染。

默认行为是在每次状态更改时重新渲染,在绝大多数情况下,您应该依赖默认行为。

如果您不希望您的子组件在某些情况下重新渲染,您可以使用 shouldComponentUpdate 生命周期。这个生命周期只是一个性能优化。 Read about shouldcomponentupdate

还可以考虑使用 PureComponent 代替组件。它对 props 和 state 进行了浅层比较,并减少了您跳过必要更新的机会。 Read about PureComponent

【讨论】:

以上是关于子组件如何在不监听生命周期方法的情况下从父组件接收 props?的主要内容,如果未能解决你的问题,请参考以下文章

父组件可以监听到子组件的生命周期吗?

如何在不使用角度的ng的情况下将输入值从父组件传递给子组件?

vue 生命周期 和 生命周期的执行顺序

vue 父组件监听子组件生命周期

父组件监听子组件的生命周期

React+ANTD项目使用后的一些关于生命周期比较实用的心得