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.
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 :)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:
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).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!)