当前位置: 首页 > 面试题库 >

此.props.children不会在父状态更改时重新呈现

翟志新
2023-03-14
问题内容

我有一段代码

import React, {Component} from 'react';

class App extends Component {
  render() {
    return (
      <Container>
        <Child/>
      </Container>
    )
  }
}

class Container extends Component {
  render() {
    console.log('Container render');
    return (
      <div onClick={() => this.setState({})}>
        {this.props.children}
      </div>
    )
  }
}

class Child extends Component {
  render() {
    console.log('Child render');
    return <h1>Hi</h1>
  }
}

export default App;

单击“ Hi”消息时,仅Container组件会继续重新渲染,而Child组件不会重新渲染。

为什么ChildContainer状态更改时不重新渲染组件?

我想说,由于它是Container组件的一个属性而不会发生,但是仍然会this.props.childChildJSX中的组件评估,所以不确定。

<div onClick={() => this.setState({})}>
  {this.props.children}
</div>

完整示例https://codesandbox.io/s/529lq0rv2n(检查控制台日志)


问题答案:

这个问题已经很老了,但是由于您似乎没有得到满意的答案,因此我也会尝试一下。

正如您自己观察到的,改变

// Scenario A

<div onClick={() => this.setState({})}>
  {this.props.children}
</div>

// Scenario B

<div onClick={() => this.setState({})}>
  <Child />
</div>

事实上,最终会

容器渲染
儿童渲染

在控制台中,每次单击。

现在,引用你

据我所知,如果触发了setState(),则将调用Container组件的render函数,并且应重新渲染所有子元素。

您似乎非常接近了解这里发生的情况。

到目前为止,你是正确的,因为Containerrender执行,因此必须从它返回的组件调用自己的render方法。

现在,正如您还说的那样,

<Child />

// is equal to

React.createElement(Child, {/*props*/}, /*children*/)

本质上,您从以上内容中获得的只是一个object描述要在屏幕上显示的内容, 一个React Element

这里的关键是要了解 React.createElement(Child, {/*props*/}, /*children*/)执行发生,在上述各场景。

因此,让我们看看发生了什么:

class App extends Component {
  render() {
    return (
      <Container>
        <Child/>
      </Container>
    )
  }
}

class Container extends Component {
  render() {
    console.log('Container render');
    return (
      <div onClick={() => this.setState({})}>
        {this.props.children}
      </div>
    )
  }
}

class Child extends Component {
  render() {
    console.log('Child render');
    return <h1>Hi</h1>
  }
}

您可以这样重写返回值App

<Container>
  <Child/>
</Container>

// is equal to

React.createElement(
  Container, 
  {}, 
  React.createElement(
    Child, 
    {}, 
    {}
  )
)

// which is equal to a React Element object, something like

{
  type: Container,
  props: {
    children: {
      type: Child,    // |
      props: {},      // +---> Take note of this object here
      children: {}    // |
    }
  }
}

您还可以Container像这样重写返回值:

<div onClick={() => this.setState({})}>
  {this.props.children}
</div>

// is equal to

React.createElement(
  'div', 
  {onClick: () => this.setState({})}, 
  this.props.children
)

// which is equal to React Element

{
  type: 'div',
  props: {
    children: this.props.children
  }
}

现在,this.props.childrenApp返回的React Element中包含的内容相同:

{
  type: Child,
  props: {},
  children: {}
}

确切地说,这两种情况在 引用上 是相同的,这意味着在两种情况下,它们在内存中都是完全相同的。

现在,无论Container重新渲染多少次,由于渲染children之间总是参照相同的事物(因为React
Element是在App关卡中创建的,并且没有理由更改),因此它们不会重新渲染。

简而言之, 如果React Element参照( )等于前一个渲染中的 元素React不会再次===渲染它。

现在,如果要更改,Container您将拥有:

<div onClick={() => this.setState({})}>
  <Child />
</div>

// is equal to

React.createElement(
  'div', 
  {onClick: () => this.setState({})}, 
  React.createElement(
    Child, 
    {}, 
    {}
  ) 
)

// which is equal to

{
  type: 'div',
  props: {
    children: {
      type: Child,
      props: {},
      children: {}
    }
  }
}

但是, 在这种情况下,如果要重新渲染Container,则必须重新执行

React.createElement(
  Child, 
  {}, 
  {}
)

对于每个渲染 。这将导致React元素在渲染之间具有引用上的差异,因此Child即使最终结果相同,React也会实际上也重新渲染组件。

参考



 类似资料:
  • 问题内容: 我要说的是今天要学习react和redux,但是我不知道如何在状态更改后强制组件重新渲染。 这是我的代码: 我可以触发更新的唯一方法是使用 在构造函数内部,以便我手动触发组件的更新状态以强制重新渲染。 但是如何链接存储状态和组件状态? 问题答案: 仅当组件的状态或道具发生更改时,组件才会重新渲染。您不是依靠this.state或this.props,而是直接在render函数中获取存储

  • 我猜这可能与从父级打开有关,但我有其他组件,它们内部的状态发生变化,所以我有点困惑,为什么这个组件不尊重它的新状态。 谢谢

  • 我有一个数组列表 记录在子组件中,它返回给我初始数组。 从API更改数据后 如果我在函数中将该数组记录在父组件中,我将得到一个对象数组。 它正在更改 ,但子组件没有。 我该怎么办??

  • 我正在学习如何应对,我整天都在试图找到解决问题的办法,但都没有成功。然后决定在这里提出我的第一个问题。 我有子组件,包括React-Datepicker组件和单独的“第二天”和“前一天”按钮来更改选定的日期。 SelectedDate存储在父组件的状态中。 我试图从子组件更新父组件的状态,当状态更新时,子组件应该重新呈现,因为该状态作为道具传递给同一个子组件。 我已设法从child更改父状态,但子

  • 在父组件中: 我有一个布尔状态: 我将其发送到子组件: 根据布尔值,我希望它呈现不同的组件。

  • 我有一个带有两组按钮(功能和目标)的界面。当我点击一个按钮时,我希望它从一个团队转到另一个团队。我正在用react和redux实现这一点。我唯一的问题是,当状态更新并且我成功地记录了更新的状态时,除非我使用forceUpdate(),否则组件不会更新。我不明白的是,既然状态更新成功,组件不应该自动重新渲染吗? 一些js 正如您所看到的,当我单击一个按钮时,我触发updateLists函数,该函数将