使用 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 请求。
- 我注意到 ParentComponent 中的
if (Object.keys(DriverCommissionResults).length > 0)
表达式总是为假,对吧?因为 DriverCommissionResults
只是一个空对象,在检查之前初始化了两行 :)
- 尝试从
PureComponent
扩展 RowComponent
,这将确保 RowComponent
仅在某些 props 确实发生更改时才重新渲染(请参阅文档:https://reactjs.org/docs/react-api.html#reactpurecomponent)
但我不喜欢你在这里所做的整个想法。
您基本上是在单击按钮时更改 ParentComponent 的状态,并在组件接收道具时产生副作用(在这种情况下调用 redux)。
我会建议:
- in
ParentComponent
- 在 Button.onClick 中间产生副作用(更新数据库)(保持状态变化,因为你可能需要某种等待指示器)。
- in
RowComponent
- 如果你正在做一些副作用 - 更好的地方是 componentDidMount
或 componentDidUpdate
(但在第二位你最好总是检查道具是否真的不同来自以前的!)
此处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 请求。
- 我注意到 ParentComponent 中的
if (Object.keys(DriverCommissionResults).length > 0)
表达式总是为假,对吧?因为DriverCommissionResults
只是一个空对象,在检查之前初始化了两行 :) - 尝试从
PureComponent
扩展RowComponent
,这将确保RowComponent
仅在某些 props 确实发生更改时才重新渲染(请参阅文档:https://reactjs.org/docs/react-api.html#reactpurecomponent)
但我不喜欢你在这里所做的整个想法。 您基本上是在单击按钮时更改 ParentComponent 的状态,并在组件接收道具时产生副作用(在这种情况下调用 redux)。 我会建议:
- in
ParentComponent
- 在 Button.onClick 中间产生副作用(更新数据库)(保持状态变化,因为你可能需要某种等待指示器)。 - in
RowComponent
- 如果你正在做一些副作用 - 更好的地方是componentDidMount
或componentDidUpdate
(但在第二位你最好总是检查道具是否真的不同来自以前的!)