使用 React 生命周期方法为子组件中的每个用户制作 POST 请求和更新数据库

Make POST request and update DB for each and every user in Child Component, using React Life Cycle Method

此处Table显示用户上月工资明细。单击“更新”按钮时,系统将检索本月的必要数据并计算新的薪水和属性,并将更新子组件 table 值。子组件也有其他子组件按钮。 使用新值更新 table raws 时“需要为每个用户发出 post 请求并迭代更新数据库”。这里无限循环发生(infinity POST 请求更新 DB)渲染子组件及其子组件时。

能否建议一种将每个用户详细信息更新到数据库的方法。在子组件“RowComponent”中调用Redux action function(this.props.updateUserLog(newUserLog.handle,userDetails))的方式.重新渲染它的子项时,POST 请求不得循环发送。

~父组件~

import { getDriverCommissionAlcohol } from "../redux/actions/dataActions";

class DriverPerfomance extends Component {
  constructor(props = {}) {
    super(props);

    this.state = {
      press: false,
    };
  }

  UpdatePerformance = (event) => {
    this.setState({ press: true });
    this.props.getDriverCommissionAlcohol(month, year);
  };

  render() {
    const {
      data: {
        drivers: { user, month, year, createdAt },
        performance: { driverCommission, alcoholStatus },
      },
      UI: { loadingOffScrean },
    } = this.props;

    let DriverCommissionResults = {};

    if (this.state.press) {
      let combinedUser = {};
      let recent = [];

      if (Object.keys(DriverCommissionResults).length > 0) {
        combinedUser.forEach((filteredPerson) => {
          recent.push(
            <RowComponent
              key={filteredPerson.userId}
              handle={filteredPerson.username}
              monthRetrive={this.state.month}
              yearRetrive={this.state.year}
              month={month}
              year={year}
              drunkenPesentage={filteredPerson.drunkenPesentage}
              press={true}
              newMonthCalculationDone={true}
            />
          );
        });
      } else {
        recent = (
          <Fragment>
            {user.map((filteredPerson) => (
              <RowComponent
                key={filteredPerson.userId}
                handle={filteredPerson.username}
                month={month}
                year={year}
                press={false}
                newMonthCalculationDone={false}
              />
            ))}
          </Fragment>
        );
      }
    }

    return (
      <Fragment>
        <Button disabled={loadingOffScrean} onClick={this.UpdatePerformance}>
          Update
        </Button>
        <table>
          <thead>
            <tr>
              <th></th>
            </tr>
          </thead>
          <tbody>{recent}</tbody>
        </table>
      </Fragment>
    );
  }
}

~ 子组件 ~

import { updateUserLog } from "../redux/actions/dataActions";

class RowComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      handle: "",
      createdAt: "",
      ranking: 0,
      year: "",
      month: "",
    };
  }

  componentWillReceiveProps() {
    const newUserLog = {
      handle: this.props.handle,
      createdAt: new Date().toISOString(),
      ranking: NewRankingCalculate,
      year: this.props.yearRetrive ? this.props.yearRetrive : this.props.year,
      month: this.props.monthRetrive ? this.props.monthRetrive : "",
    };

    this.mapUserDetailsToState(newUserLog);
  }

  mapUserDetailsToState = (newUserLog) => {
    this.setState({
      handle: newUserLog.handle ? newUserLog.handle : "",
      createdAt: newUserLog.createdAt ? newUserLog.createdAt : "",
      ranking: newUserLog.ranking ? newUserLog.ranking : "",
      year: newUserLog.year ? newUserLog.year : "",
      month: newUserLog.month ? newUserLog.month : "",
    });

    const userDetails = {
      handle: newUserLog.handle,
      createdAt: newUserLog.createdAt,
      ranking: newUserLog.ranking,
      year: newUserLog.year,
      month: newUserLog.month,
    };

    this.props.updateUserLog(newUserLog.handle, userDetails);
  };

  render() {
    const {
      member: { username, year, month, salary },
    } = this.props;
    let action = (
      <DrunkenLog
        handle={username}
        month={this.state.month !== "" ? this.state.month : month}
        year={this.state.year !== "" ? this.state.year : year}
      />
    );
    <tr>
      <td>{initialSalary}</td>
      <td>{this.state.salary !== 0 ? this.state.salary : salary}</td>
      <td>{action}</td>
    </tr>;
  }
}

期望: 通过在子组件生命周期方法中调用 POST 请求函数,为每个用户更新 DB table。停止无限循环 POST 请求。并在更改道具后发出 post 请求。

  1. 我注意到 ParentComponent 中的 if (Object.keys(DriverCommissionResults).length > 0) 表达式总是为假,对吧?因为 DriverCommissionResults 只是一个空对象,在检查之前初始化了两行 :)
  2. 尝试从 PureComponent 扩展 RowComponent,这将确保 RowComponent 仅在某些 props 确实发生更改时才重新渲染(请参阅文档:https://reactjs.org/docs/react-api.html#reactpurecomponent

但我不喜欢你在这里所做的整个想法。 您基本上是在单击按钮时更改 ParentComponent 的状态,并在组件接收道具时产生副作用(在这种情况下调用 redux)。 我会建议:

  1. in ParentComponent - 在 Button.onClick 中间产生副作用(更新数据库)(保持状态变化,因为你可能需要某种等待指示器)。
  2. in RowComponent - 如果你正在做一些副作用 - 更好的地方是 componentDidMountcomponentDidUpdate (但在第二位你最好总是检查道具是否真的不同来自以前的!)