当前位置: 首页 > 知识库问答 >
问题:

如何获得状态更新基于更新到道具?

上官英哲
2023-03-14

我有一个组件,看起来像:


class Table extends Component {
  constructor(props) {
    super(props);

    this.columnDefs = columnDefs;
    this.state = {
      isLoading: true,
      showTimeoutModal: false,
      tableData: [],
      currentDate: null
    };
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    this.setState({
      isLoading: true,
      currentDate: this.props.currentDate
    });

    someApi.getData(this.props.currentDate).then(tableData => this.setState({
      tableData: tableData,
      isLoading: false
    }))
      .catch(error => {
        if (error.message === 'timeout') {
          this.setState({
            showTimeoutModal: true
          });
        } else {
          throw new Error(error.message);
        }
      });
  }

  onGridReady(params) {
    this.gridApi = params.api;
    this.gridApi.sizeColumnsToFit();
  }

  renderGrid() {
    const { tableData, isLoading, showTimeoutModal } = this.state;
    let currentView = null;
    console.log(this.props.currentDate);
    console.log(this.state.currentDate);
    if (!isLoading) {
      if (tableData) {
        currentView =
          <div>
            <AgGridReact
              columnDefs={this.columnDefs}
              rowData={tableData}
              pagination
              paginationPageSize={25}
              headerHeight="43"
              onGridReady={params => this.onGridReady(params)}
              rowSelection="single"
              animateRows="true" />
          </div>;
      } else {
        currentView = <h6>There is no job data to display!</h6>;
      }
    } else if (showTimeoutModal) {
      currentView = <div>
        <TimeoutModalComponent />
        <h6>Timed out</h6>
      </div>;

    } else {
      currentView = <LoadingComponent />;
    }

    return (
      <div>

        {currentView}
      </div>
    );
  }

  render() {
    return (
      <div>
        {this.renderGrid()}
      </div>
    );
  }

}

export default Table;

它从datepicker组件获取currentDate属性,如下所示:


class DatePicker extends Component {
  constructor(props) {
    super(props);
    this.onDateChange = this.onDateChange.bind(this);
    this.state = {
      currentDate: moment(),
      focused: false
    };
  }

onDateChange() {
    this.setState({
      currentDate: this.props.currentDate
    });
  }

  render() {
    return (
      <div className="form-group">


        <SingleDatePicker
          date={this.state.currentDate}
          onDateChange={this.onDateChange}
          focused={this.state.focused}
          onFocusChange={({ focused }) => this.setState({ focused: focused })}
        />
        <TableComponent currentDate={`${this.state.currentDate}`} onDateChange={this.onDateChange} />
      </div>

    );
  }
}

export default DatePicker;

当我从日期选择器中选择新日期时,this.props.current子组件上的日期会更新。这是我想要的日期。但是,当更新该prop时,它不会用新的预期数据重新呈现表。我意识到我必须更新子表的状态才能重新渲染。我试图通过设置当前日期:this.props.current日期来设置ftchData()方法中的状态。但是这不起作用,它不会实时更新状态,因此网格不会重新渲染。我想我在概念上错过了一些关于反应的东西,但我不确定是什么。我认为datePicker组件很好,因为它可以在选择日期时发送正确的日期,并且可以将该日期传递给表组件。谁能告诉我为什么这个状态不会更新?或者更好的是,当this.props.current日期更新时,处理状态更改的最佳方法是什么?

编辑:我现在可以获得要更改的状态

componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.currentDate !== this.state.currentDate) {
  this.setState({currentDate: nextProps.currentDate});
}

}

但它仍然不会在更新时重新呈现表。

共有2个答案

空谦
2023-03-14

在Table和DatePicker组件中,使用组件didUpdate(PreProps)捕获道具更改事件。

避免使用组件WillReceiveProps。

根据react,使用此生命周期方法通常会导致错误和不一致。组织机构

酆乐湛
2023-03-14

好的,我可以看到您有多个问题:

  • 您在日期选择器组件中管理currentDate的状态,这是一个巨大的危险信号,是一个巨大的禁忌,您需要更好地理解“提升状态”

您希望将组件和日期选择器组件放在父组件中,该父组件控制表组件和日期选择器组件的布局,并管理这两个组件之间共享的状态。这一改变将彻底改变你的方法,解放你的思想,更好地管理你的ReactJs应用程序。这是“提升状态”。您会发现,在我建议的重构之后,您的重新渲染问题很可能根本不存在。

 类似资料:
  • 您可能知道,在正常模式下,当状态更新时,我们使用更新依赖项来获得通知,如下所示: 但在我的例子中,我的状态中有一个数组,我正在尝试在useEffect的循环中更新它,如下所示: 在本例中,每次forEach循环运行时,我都会得到初始val(我知道,因为val不是useffect的依赖项),但如果我将其作为依赖项,它将更新两次。解决这个问题的办法是什么? 编辑:基本上,我的意思是,当我在useffe

  • 问题内容: 我在使用React表单和正确管理状态时遇到麻烦。我有一个形式为模式的时间输入字段。初始值在中设置为状态变量,并从父组件传递。这本身工作正常。 当我想通过父组件更新默认的start_time值时,就会出现问题。更新本身通过发生在父组件中。但是在我的表单中,默认的start_time值从不更改,因为它仅在中定义一次。 我尝试过通过强制进行状态更改,该更改确实有效,但给了我错误。 所以我的问

  • 问题内容: constructor(){ super(); this.state = { address: { street:null, city:null, postalCode: null } }; } postalCodeChange(e){ this.setState.address.postalCode = e.target.value; console.log(this.state);

  • 说明 支付宝境外到店支付-更新商户二维码状态 官方文档:https://global.alipay.com/service/merchant_QR_Code/34 类 请求参数类 请求参数 类名:\Yurun\PaySDK\AlipayCrossBorder\InStore\ModifyStatus\Request 属性 名称 类型 说明 $service string 接口名称 $timesta

  • 我在我的项目中使用React钩子,需要尝试解决如何在状态值发生变化时动态地将类添加到

  • 我是新来的反应。我被困在这件事上,真的很感激你的帮助! 父组件将把一个数组传递到这个子组件中。当我console.log(this.props.repairs)时,它显示了一个4的数组。每当传入修复数组时,我都试图更新this.state.SortedDataList。console.log(this.state)仍然将sortedDataList显示为空数组。 我做错了什么?非常感谢,谢谢你的帮