0

Here Table shows the previous month user salary details. When click the "Update" button, system will retrieve the necessary data for this month and calculate the new salary and properties and will update the child component table values. Child component has other Child Component Buttons too. When updating the table raws with new values "Need to make a post request for each and every user and update the database iterately". Here infinity looping happening(infinity POST request for update DB) when render child component and its children.

Could you please suggest a way to update each and every user details to the database. The way to call Redux action function(this.props.updateUserLog(newUserLog.handle, userDetails)) inside the child component "RowComponent". When re-rendering it's children, the POST request must not send looping.

~ Parent Component ~

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>
    );
  }
}

~ Child Component ~

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>;
  }
}

Expectation: Update DB table for each and every user, by calling POST requests function inside the child component life cycle methods. Stop the infinity looping POST requests. And make post request once changing the props.

1 Answers1

1
  1. i've noticed that if (Object.keys(DriverCommissionResults).length > 0) expression in ParentComponent will always be false, right? because DriverCommissionResults is just an empty object, initialised two rows before this check :)
  2. try extend RowComponent from PureComponent, this will ensure that RowComponent will rerender only if some of props really changed (see docs: https://reactjs.org/docs/react-api.html#reactpurecomponent)

but i don't like the whole idea of what you are doing here. You are basically change state of ParentComponent on button click, and make side effect (call redux in this case) when component is receiving props. I would suggest:

  1. in ParentComponent - make side effect (update DB) right in the middle of Button.onClick (keeping state changes, because you need some sort of wait indicator maybe).
  2. in RowComponent - if you are doing some side effects - better place for them is componentDidMount or componentDidUpdate (but in second place you better always check for props to really differ from previous ones!)
  • 1. `if (Object.keys(DriverCommissionResults).length > 0)` is not empty. It contains values. I did not add the all code. Updates values correctly in the table. No issue. But when calling the redux function for POST data for DB ```this.props.updateUserLog(newUserLog.handle, userDetails); ``` infinity post request looping happening :( – Vidumini Kulathunga Aug 05 '20 at 08:28
  • Fixed the issue as your instructions. :) Thank you. – Vidumini Kulathunga Aug 06 '20 at 04:10
  • @ViduminiKulathunga Glad to hear that! I'll be grateful if you mark my answer as "best answer" (green check icon) :) happy coding! – Виталий Абрамов Aug 06 '20 at 10:18