当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件

Posted

技术标签:

【中文标题】当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件【英文标题】:Rerendering React child component when the parent updates its props in a Next.js app 【发布时间】:2019-11-30 16:59:06 【问题描述】:

我想弄清楚如何创建简单的 React 组件,这些组件根据父组件传递给子组件的更改进行更新。当我在内部更新组件状态时,我能够达到预期的结果,但我希望组件通过更改其道具完全由其父级控制。在常规 React 中,这是微不足道的,但我一直无法弄清楚如何在 s-s-r Next.js 应用程序中完成此操作。

这是一个普遍的问题,会影响我打算构建的许多组件,但为了清楚起见,我将重点关注我目前正在处理的问题:一个可折叠的容器,它带有一个 boolean collapsed prop,它决定了是否容器已折叠。

当子组件的父组件更新其道具时,如何让 Next.js 在子组件中触发 React 生命周期方法(尤其是 componentDidUpdate),在这种情况下切换布尔值?

我已经研究过使用 getInitialProps,但根据 Next.js 文档,这仅适用于页面。同样,不出所料,它没有用。

我也尝试过 componentWillUpdateshouldComponentUpdate 甚至 getDerivedStateFromProps,但除了让组件更新在内部拥有自己的状态,这对于我的用例来说不是可接受的解决方案。

我尝试使用 React.Component 类扩展语法和无状态函数语法来创建这个组件,但都没有成功,而且它们的结果也没有明显的差异。

我想直接使用 props 并且尽可能不涉及状态,因为 React 文档建议基于 props 更新状态是不好的做法,更不用说它不应该是必要的。

   render() 
      return (
         <div className= styles.wrapper >
            <div
               className= styles.container 
               data-collapsed= this.props.collapsed 
            >
            </div>
         </div>
      );
   

真正的折叠效果是通过 CSS 根据 data-collapsed 自定义属性的值来实现的。此解决方案有效,因此我没有包含此代码。

我省略了我失败的生命周期方法尝试,但否则这显然应该是一个非常简单的组件。根据我过去使用 vanilla React 的经验,更改子道具会直接触发重新渲染,通常根本不需要任何生命周期方法。

我想要的很简单(我认为):让父组件更改 CollapsableContainer 折叠道具并相应更新。我在这里错过了什么?

【问题讨论】:

【参考方案1】:

我想通了,这有点尴尬。我正在使用外部变量而不是父级中的状态变量来测试这个解决方案。像这样:

let testBool = false;

class Example extends Component 
   render() 
      return (
         <div>
            <ComponentToUpdate
               booleanProp= testBool 
            />
            <button
               onClick=() =>  testBool = !testBool; 
            >
              Click
            </button>
         </div>
      )
   

但现在我正在这样做:

class Example extends Component 
   constructor(props) 
      super(props);
      this.state = 
         testBool: false
      
   
   render() 
      return (
         <div>
            <ComponentToUpdate
               booleanProp= this.state.testBool 
            />
            <button
               onClick=() =>  setState( testBool: !this.state.testBool ) 
            >
              Click
            </button>
         </div>
      )
   

而且它有效。现在到facepalm。希望这可以帮助其他可能出现精神胀气的人。

【讨论】:

以上是关于当父组件在 Next.js 应用程序中更新其道具时重新渲染 React 子组件的主要内容,如果未能解决你的问题,请参考以下文章

在页面加载时将道具传递给子组件 - 与 next.js 做出反应

Next.js - 页面没有让 GetServerSideProps 进入页面组件道具(使用自定义 _app.js)

在道具更改时重新渲染功能组件

Next.Js 带有样式组件的 React 应用程序。警告:道具 `className` 不匹配。服务器:“x” 客户端:“y”

React 组件道具未在 Next.js 页面中呈现

Next.js 使用 getServerSideProps 如何将道具从页面传递到组件?