【问题标题】:React doesn’t rerender component if already rendered once如果已经渲染过一次,React 不会重新渲染组件
【发布时间】:2017-09-08 11:06:32
【问题描述】:

我有一个名为 ChildComponent 的组件,我从 ParentComponent 调用它,如下所示。注意事项:

  1. 有一个“显示孩子”按钮。
  2. 在第一次单击此按钮时,它应该重新渲染子组件。但是在随后的点击中,它甚至不应该调用 ChildComponent,而是从 this.refs 中获取 dom。为此,我使用 return this.refs.chid 会出错

下面是代码。

ParentComponent= React.creatClass({
  getInitialState: function(){
    return {
      rendered: false
    }
  },
  render_or_cache: function(){
    if (this.state.rendered){
      return this.refs.child;
    }
    else {
      return <ChildComponent/>
    }
  },
  onbuttonclick: function(){
    this.setState({rendered: true})
  },
  render:function(){
    return (
      <div ref="child">
        {this.render_or_cache()}
      </div>
      <button onClick={this.onbuttonclick()}>Show Child Again</button>
    )
  }
})

ChildComponent= React.creatClass({
  render:function(){
    return (
      <div>Some Text from Child</div>
    )
  }
})

【问题讨论】:

  • 人们格式化他们的代码是有原因的:这样其他人就可以阅读代码。
  • ^ 同意。尝试将您的代码编辑为更易于阅读的格式
  • 你能解释一下你的最终目标吗?为什么ChildComponent 不应该重新渲染? ChildComponent所有 个实例是否应该只渲染一次,或者问题是如何防止ParentComponent 的特定子树重新渲染?
  • 感谢您的反馈。如果 ChildComponent 有一个由用户在初始渲染时填充的输入框怎么办。现在,如果用户再次点击“Show Child Again”按钮,它会重新渲染子组件并且输入框中的值会丢失
  • 我的意图是持久化数据。即输入框中的值。这就是为什么我不希望子组件发生新的渲染,因为在这种情况下,输入框中的值将丢失

标签: javascript reactjs


【解决方案1】:

你必须将你的组件存储在state

试试这个

代码:

ParentComponent= React.creatClass({
getInitialState: function(){
   return {
             childComponent :[]
          }
},

onbuttonclick: function(){
   this.setState({childComponent.concat(<ChildComponent/>)})
}
render:function(){

return (
      <div ref="child">
           {this.state.childComponent}
     </div>
     <button onClick={this.onbuttonclick()}>Show Child Again</button>
)}
})

ChildComponent= React.creatClass({
render:function(){

return (
        <div>Some Text from Child</div>
)}
})

【讨论】:

    【解决方案2】:

    您的术语用法有些不一致。

    Mounting 是当一个组件没有使用时存在,然后存在。挂载从初始状态开始,包括渲染。

    重新渲染发生在组件的属性/状态发生变化,但组件层次结构不变时。这会保留组件状态。

    我不确定你是如何通过返回 this.refs.child 来完成你所说的。完成这样的单次效果的一种简单方法是简单地有条件地渲染元素,如下所示:

    render:function(){
    const child = (this.state.rendered) ? <ChildComponent/> : ""
    
    return (
          <div>
               {child}
         </div>
         <button onClick={this.onbuttonclick()}>Show Child Again</button>
    )}
    })
    

    请注意,在这种方法中,将 rendered 从 true 更改为 false 将导致 ChildComponent 卸载,从而丢失该组件实例的状态。我想在大多数情况下,这都是想要的行为。

    【讨论】:

    • 谢谢。 ChildComponent 的 id 有一个输入框,该输入框由用户在初始渲染时填充。现在再次如果用户点击“Show Child Again”按钮,它会重新渲染子组件并且输入框中的值会丢失。
    【解决方案3】:

    何时使用参考

    refs 有几个很好的用例:

    管理焦点、文本选择或媒体播放。触发 命令式动画。与第三方 DOM 库集成。 避免对任何可以以声明方式完成的事情使用 refs。

    例如,而不是公开 open() 和 close() 方法 对话框组件,传递一个 isOpen 属性给它。

    https://facebook.github.io/react/docs/refs-and-the-dom.html

    出于您的目的,您可以通过检查您的状态并决定您应该渲染哪个组件来使用条件渲染。 https://facebook.github.io/react/docs/conditional-rendering.html

    希望对你有帮助。

    【讨论】:

      【解决方案4】:

      在我看来,你正在跳跃篮球以实现 React 已经做得非常好的事情;确定何时重新渲染组件以及何时更新 DOM。

      如果你比 React 更清楚何时重新渲染一个组件,你可以在你的组件上定义一个 shouldComponentUpdate(nextProps, nextState) 方法,它获取组件的下一个 props 和状态,并根据你的返回 truefalse自己的规则。

      查看 React 文档中的生命周期方法:https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate

      【讨论】:

        猜你喜欢
        • 2023-03-13
        • 2020-02-13
        • 2021-09-19
        • 2023-03-28
        • 1970-01-01
        • 2016-05-09
        • 2021-06-07
        • 1970-01-01
        • 2022-11-29
        相关资源
        最近更新 更多