javascript – 修复未重新渲染的子组件的方法(由于数据的更改是作为props而不是状态传递的)?

背景

我正在使用一个使用ReactJS作为渲染库的Meteor应用程序.

目前,我在更新数据时重新渲染子组件时遇到问题,即使父进程正在访问更新的数据&据说把它传给了孩子.

Parent组件是一个数据表.子组件是单击编辑日期字段.

它(理论上)的工作方式:父组件将日期的现有数据作为prop传递给子组件.子组件获取现有的道具数据,处理它和它.设置一些使用它的状态,然后有两个选项:

>默认:显示数据
>如果用户点击数据字段:更改为输入&允许用户选择日期(使用react-datepicker),更改状态 – 当用户点击字段外,触发返回仅显示&将更新的数据从状态保存到数据库

我在表中每行使用子组件两次,每次使用它时,它需要访问数据库中的最新日期数据.因此,如果数据在一个字段中更改,则第二个字段应反映该更改.

问题

除非我手动刷新页面并强制子组件使用新数据进行渲染,否则第二个字段不会反映数据库中的更改.编辑的字段反映了数据的变化,因为它反映了存储在状态中的内容.

阅读完React文档之后,我确定问题是因为日期是作为一个prop进入,然后作为一个状态处理 – 并且因为该组件不会从prop更改中重新呈现.

我的问题

我该怎么做才能解决这个问题?

我对文档所做的所有阅读强烈建议远离诸如forceUpdate()和getDerivedStateFromProps()之类的东西,但结果我不确定如何通过我想要的方式传递数据.

思考?

我的守则

我已经将代码缩写了一点点&删除了特定于我的项目的变量名称,但如果它有帮助,我可以提供更多的实际名称.我认为我的问题比直接调试更具概念性.

ParentComponent () {
    //Date comes as a prop from database subscription
    var date1 = this.props.dates.date1 
    var date2 = this.props.dates.date2
    return(
        

儿童

ChildComponent() {
    constructor(props) {
        super(props);
        this.state = {
            date1: this.props.selected[0],date2: this.props.selected[1],field: false,};
    }

    handleDatePick() {
        //Handles the event listeners for clicks in/out of the div,handles calling Meteor to update database.
    }
    renderDate1() {
        return(
            

(如果这个代码/我的解释很粗糙,那是因为我还是一个相当初学者/低级别的开发人员.我没有接受过正式培训,所以我在学习一个非常困难的应用程序时正在学习.独唱开发者.这是一个很长的故事.请温柔!)

最佳答案
React文档有一个关于constructor()最佳实​​践用法的部分.阅读,密切注意黄色突出显示的“注意”部分,应该说明你遇到的确切问题.

本质上,constructor()只运行一次,最常用于初始化内部/本地状态(或绑定方法).这意味着当为该子项调用constructor()时,您的子组件将使用所选prop的值设置date1和date2.无论选择的值是什么,在构造函数()被调用时将被设置为子状态,并且即使值继续更改也将保持不变.

因此,传递给子组件的所选prop的任何连续更新都不会反映在该组件的内部状态中,这意味着不会重新呈现该组件.您需要在子组件的其他位置使用React的setState()方法来正确更新该子级的状态并触发重新呈现.

使用React生命周期方法的组合来正确更新子组件是可行的方法.下面的代码片段为您提供了有关在componentDidMount()和componentDidUpdate()中实现更改的主要想法

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date1: 0,date2: 0,};
  }

  /*
    Any time the child mounts to the DOM,you can use the method below to set 
    your state using the current value of your 
    selected prop from the parent component...
  */

  componentDidMount() {
    this.setState({
      date1: this.props.selected[0],date2: this.props.selected[1]
    });
  }

  /* 
   When the child receives an update from its parent,in this case a new date selection,and should 
   re-render based on that update,use the method below 
   to make a comparison of your selected prop and then 
   call setState again...
  */

  componentDidUpdate(prevProps) {
    if (prevProps.selected !== this.props.selected) {
      this.setState({
        date1: this.props.selected[0],date2: this.props.selected[1]
      });
    }
  }

  render() {
    const { date1,date2 } = this.state;
    return (