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

我想弄清楚如何创建简单的 React 组件,这些组件根据父组件传递给子组件的更改进行更新。当我在内部更新组件状态时,我能够达到预期的结果,但我希望组件通过更改其道具完全由其父级控制。在常规 React 中,这是微不足道的,但我一直无法弄清楚如何在 SSR 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 折叠道具并相应更新。我在这里错过了什么?

【问题讨论】:

    标签: reactjs next.js


    【解决方案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。希望这可以帮助其他可能出现精神胀气的人。

    【讨论】:

      猜你喜欢
      • 2018-10-07
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 2019-06-01
      • 2019-01-31
      • 2020-07-18
      • 2021-06-26
      • 2018-08-12
      相关资源
      最近更新 更多