在 React 中通过更改父级的道具来更新子组件

Posted

技术标签:

【中文标题】在 React 中通过更改父级的道具来更新子组件【英文标题】:Updating Child Component Via Change of Props from Parent in React 【发布时间】:2016-12-10 02:27:33 【问题描述】:

我有一个组件,其状态作为道具传递给子组件。我注意到即使父组件的状态发生了变化,子组件也不会重新渲染。

基于使用 shouldComponentUpdate 的官方 React 文档:

"第一次渲染内部组件时,它将有 foo: 'bar' 作为 value 属性。如果用户点击锚点, 父组件的状态将更新为 value: foo: 'barbar' ,触发内部组件的重新渲染过程,即 将收到 foo: 'barbar' 作为道具的新值​​。

问题是由于父组件和内部组件共享一个 引用同一个对象,当对象在第 2 行发生变异时 在 onClick 函数中,内部组件的 prop 会发生变化。 所以,当重新渲染过程开始时,shouldComponentUpdate 被调用,this.props.value.foo 将等于 nextProps.value.foo,因为其实 this.props.value 引用了 与 nextProps.value 相同的对象。

因此,因为我们会错过 prop 和 short 的变化 电路重新渲染过程,用户界面不会从“栏”更新 到 'barbar'。”

如果我不能使用 shouldComponentUpdate,我将如何强制子组件根据 Parent 的 props 更改重新渲染?

父组件

我希望子组件根据提供给 showDropzone 的布尔值重新渲染。

     <Dropzone 
      onDrop=this.onDrop 
      clearFile = this.clearFile
      showDropzone = this.state.filePresent/>

子组件

export default class Dropzone extends Component 
  constructor(props) 
    super(props);
  

  render() 
    const  onDrop  = this.props;
    const showDropzone = this.props;
    const clearFile = this.props;

    return (
      <div className="file-adder">
          <div className="preview">
            showDropzone? 
            <Dropzone
              onDrop=onDrop
              ref="dropzone">
            </Dropzone>           
            :<button type="button" 
            className="btn btn-primary"
            onClick=clearFile>
            Clear File</button>
        </div>
    </div>
    );
  

【问题讨论】:

您确定命名正确吗?子组件称为 Dropzone,但它的渲染函数也渲染一个子 . 【参考方案1】:

很抱歉,您的代码有很多错误

首先(这是一个提示)里面:

 const  onDrop  = this.props;
 const  showDropzone  = this.props;
 const  clearFile  = this.props;

你可以写一行

 const  onDrop, showDropzone, clearFile  = this.props;

现在你的问题从这里开始:

您在 大括号 中使用了 showDropzone,这是您的 问题删除它们

你的错误showDropzone? firstOption : anotherOption

将是 showDropzone? firstOption : anotherOption


另一个错误:

您在其内部使用了 Dropzone 组件,这是一个大错误

这里不能使用 Dropzone 组件showDropzone? &lt;Dropzone .../&gt; : anotherOption 你可以从另一个组件中使用它


最后我尝试格式化你的代码,让它变成这样

父组件

 this.state.filePresent
   ? <Dropzone onDrop=this.onDrop />
   : <button
         type="button" 
         className="btn btn-primary"
         onClick=clearFile
         children="Clear File"
     />

子组件

class Dropzone extends Component 
  render() 
    const  onDrop  = this.props;

    return (
      <div className="file-adder">
        <div className="preview" onDrop=onDrop ref="dropzone">
          <p>Hi! This is Dropzone component</p>
        </div>
      </div>
    );
  


export default Dropzone;

【讨论】:

【参考方案2】:

在子组件中,您使用了“showZone”而不是“showDropzone”。

谢谢

【讨论】:

谢谢!这是我的一个小错误,我试过了,它仍然不起作用 你想更新按钮点击“clearFile”的状态吗? 父组件中的 showZone 状态更新为 true 和 false。我可以更新父状态。我的问题出在子组件中,只有 组件显示。即使我有 showDropzone,清除文件按钮也不会显示?检查 showDropzone 是真还是假 您能否在使用变量的渲染方法中尝试该条件并渲染该变量作为回报,并将该 onclick 与 this 绑定:render() var showButton = if(this.props.showDropzone) showButton = else showButton = return( showButton ) 谢谢,我不确定语法是否正确,我今晚会处理这个

以上是关于在 React 中通过更改父级的道具来更新子组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react.js 中跨子组件持久化数据或状态?

在不改变状态、道具或父级的情况下反应子级渲染

即使道具没有改变,为啥还要对重新渲染组件做出反应?

React 父/子状态更改设计问题

我可以使用react中的useEffect挂钩从子级设置父级的状态

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