componentWillReceiveProps 多次渲染
Posted
技术标签:
【中文标题】componentWillReceiveProps 多次渲染【英文标题】:componentWillReceiveProps render multiple times 【发布时间】:2020-06-17 08:40:33 【问题描述】:我正在使用三个不同的函数从我的数据库中获取数据,但正如我所见,在这种情况下 componentWillReceiveProps 会重新渲染三次,这会导致我在前端复制我的元素。我怎样才能只渲染一次,或者只有对象的道具真正改变。到现在为止,我的 follow[] 数组对象都在复制
class UserDashboard extends React.Component
state =
uid: this.props.userDetails.uid,
page: 1,
redirect: false,
target: 15,
selectedRole: 4,
selectedSourceRole: 1,
quote_nr: '',
source_id: '',
status_id: '',
cost: '',
rebate: '',
pageLoading: false,
date: '2222-01-02',
therapists:[],
globalTargets:[],
follows:[],
utc: new Date().toISOString().slice(0, 19).replace('T', ' '),
topProfilesUrl = 'therapists/top/profiles';
getGlobalTargets = 'owner/targets';
followActivities = 'user/follow/activities';
componentDidMount = () =>
const getActivities,getFollowActivities,getTarget = this;
getActivities();
getFollowActivities();
getTarget();
window.scrollTo(0, 0);
UNSAFE_componentWillReceiveProps = (newProps) =>
let apiDat = newProps.apiDat;
let apiData = newProps.apiData;
if (apiData.activities && apiData.activities.success )
let therapists = apiData.activities.therapists;
let hasMore = true;
console.log("unu")
if (therapists.length < 10)
hasMore = false;
this.setState(() => (
therapists: this.state.therapists.concat(therapists),
hasMore: hasMore,
pageLoading: false
))
if (apiDat.targets && apiDat.targets.success)
console.log("doi")
let globalTargets = apiDat.targets.globals;
let hasMore = true;
if (globalTargets.length < 10)
hasMore = false;
this.setState(() => (
globalTargets: this.state.globalTargets.concat(globalTargets),
))
if (apiData.followActivities && apiData.followActivities.success)
console.log("trei")
let follows = apiData.followActivities.follows;
let hasMore = true;
if (follows.length < 10)
hasMore = false;
this.setState(() => (
follows: this.state.follows.concat(follows),
))
getTarget = () =>
this.setState(pageLoading: true, () => this.loadTargets() )
loadTargets = () =>
console.log("load")
this.props.actions.reqGetGlobalTargets(
body: ,
headers: null,
resource: `$this.getGlobalTargets?page=$this.state.page`
)
getFollowActivities= () =>
this.setState(pageLoading: true, () => this.loadFollowActivities() )
loadFollowActivities = () =>
console.log("load")
this.props.actions.reqGetFollowActivities(
body: ,
headers: null,
resource: `$this.followActivities?page=$this.state.page`
)
renderLeads = () =>
return (
this.state.globalTargets.slice(0,1).map( (t, idx) => (
t.daily_leads
))
)
renderSales = () =>
return (
this.state.globalTargets.slice(0,1).map( (t, idx) => (
t.daily_sales
))
)
renderRatio = () =>
return (
this.state.globalTargets.slice(0,1).map( (t, idx) => (
t.close_ratio
))
)
getActivities = () =>
this.setState(pageLoading: true, () => this.loadActivities() )
loadActivities = () =>
this.props.actions.reqGetTherapistsTopProfiles(
body: ,
headers: null,
resource: `$this.topProfilesUrl?page=$this.state.page`
)
renderActivities = () =>
const items = this.state.therapists.map( (t, idx) => (
<tr key=t.id className="activity-display-table">
<td>Quote Nr.: t.quote_nr</td>
<td>Source: t.source_id</td>
<td>Status: t.status_id</td>
<td>Cost: $t.cost</td>
<td>Rebate: $t.rebate</td>
<td>Date: t.date.slice(0,10).replace(/-/g,'-')</td>
</tr>
))
return (
<div ref=0 className="therapist-list">
<h2>Your Past Entries: </h2>
items
</div>
)
renderFollowActivities = () =>
const items = this.state.follows.map( (t, idx) => (
<tr key=t.id className="activity-display-table">
<td>Quote Nr.: t.quote_nr</td>
<td>Source: t.source_id</td>
<td>Status: t.status_id</td>
<td>Cost: $t.cost</td>
<td>Rebate: $t.rebate</td>
<td>Date: t.date.slice(0,10).replace(/-/g,'-')</td>
</tr>
))
return (
<div ref=0 className="therapist-list">
items
</div>
)
submitUrl = 'registerActivities';
handleChange = (eve) =>
let inputName = eve.target.name,
value = eve.target.value;
this.setState(() =>
return [inputName]: value
)
handleSubmit = () =>
this.setState(() =>
const acBody =
quote_nr: this.state.quote_nr,
cost: this.state.cost,
source_id: this.state.selectedSourceRole,
status_id: this.state.selectedRole,
date: this.state.utc,
rebate: this.state.rebate,
user_id:this.state.uid,
this.props.actions.reqActionsUsers(acBody, this.submitUrl);
)
handleStatusChange = (event) =>
let statusId = event.target.value;
this.setState(() => (
selectedRole: statusId
))
handleSourceChange = (ev) =>
let statusId = ev.target.value;
this.setState(() => (
selectedSourceRole: statusId
))
render ()
console.log(this.state.follows);
return (
<MainWrapper>
<div id="user-dashboard">
<HeaderUser logoutRedirect="/signin"/>
<div className="page-background">
<SidebarUser page="dashboard"/>
/* Page Content */
<div className="inner-content">
<div className="top-row">
<h1>Salesperson Dashboard</h1>
</div>
<div className="second-row">
</div>
<div className="activity-table">
<table className="a">
<tr>
<th>Today's Targets (this.state.utc.slice(0,10).replace(/-/g,'-'))</th>
<th>Weekly Targets</th>
<th>Bonus So Far This Week</th>
</tr>
<tr>
<td>0/this.renderLeads() Leads Handled</td>
<td>0/this.renderLeads()*5 Leads Handled</td>
<td>$0 From Leads</td>
</tr>
<tr>
<td>0/this.renderSales() Sales</td>
<td>0/this.renderSales()*5 Sales</td>
<td>$0 From Sales</td>
</tr>
<tr>
<td>0/this.renderRatio() Close Ratio</td>
<td>0/this.renderRatio()*5 Close Ratio</td>
<td>$0 From Profit Share</td>
</tr>
</table>
</div>
<div>
<h2>Leads Due For A Followup</h2>
this.renderFollowActivities()
</div>
<h2 className="activity">Add Activity</h2>
<div className="activity-menu">
<input type="text"
placeholder="Quote Number"
name="quote_nr"
onChange=this.handleChange
/>
<select onChange=this.handleSourceChange>
<option value="1">Phone</option>
<option value="2">Email</option>
<option value="3">Live Chat</option>
</select>
<select onChange=this.handleStatusChange>
<option value="4">Lead</option>
<option value="5">Sold</option>
</select>
<input type="text"
placeholder="Cost"
name="cost"
onChange=this.handleChange
/>
<input type="text"
placeholder=this.state.cost/20||("Recom. Rebate" + " $")
name="recRebate"
readOnly
/>
<input type="text"
placeholder=this.state.cost/10||("Max Possible Rebate" + " $")
name="maxRebate"
readOnly
/>
<input type="text"
placeholder="Final Rebate $"
name="rebate"
onChange=this.handleChange
/>
</div>
<ButtonRoundGradient className="activity_button" text="Add Activity" onClick=this.handleSubmit/>
this.renderActivities()
</div>
</div>
</div>
</MainWrapper>
)
const mapStateToProps = state => (
apiData: state.activities,
apiDat: state.targets,
userDetails: state.userDetails
)
function mapDispatchToProps(dispatch)
return
actions:
reqGetGlobalTargets: bindActionCreators(reqGetGlobalTargets, dispatch),
reqGetFollowActivities: bindActionCreators(reqGetFollowActivities, dispatch),
reqGetTherapistsTopProfiles: bindActionCreators(reqGetTherapistsTopProfiles, dispatch),
reqFetchUserDetails: bindActionCreators(reqFetchUserDetails, dispatch),
reqActionsUsers: bindActionCreators(reqActionsUsers, dispatch),
;
export default connect(mapStateToProps, mapDispatchToProps)(UserDashboard)
【问题讨论】:
这能回答你的问题吗? How to check what props changed in componentWillReceiveProps @Agney 这是我所做的正确的事情,它解决了问题。谢谢!!!! 【参考方案1】:ComponentWillRecieveProps
会在每次您的 state 更改或您的 state 更改时被调用,因此如果您想停止复制,您应该这样做:
componentWillReceiveProps(nextProps, nextContext)
if (JSON.stringify(nextProps.someProps.items) !== JSON.stringift(this.state.items))
// do something
基本上你应该检查你的组件的 props 和 state 是否应该对这种情况做出反应,然后真正渲染你的应用程序。
希望对你有帮助
【讨论】:
以上是关于componentWillReceiveProps 多次渲染的主要内容,如果未能解决你的问题,请参考以下文章
为啥 React 保留 componentWillReceiveProps 和 shouldComponentUpdate 方法?
react componentWillReceiveProps
如何明确替换 componentWillReceiveProps 并不断获取 nextProps?
将项目中的componentWillReceiveProps切换到getDerivedStateFromProps