admin管理员组文章数量:1401673
I would like to make sure that a function is called exactly one time, depending on some props and state.
class MyComponent extends Component {
state = {
externalInfoPresent: false,
infoSaved: false,
}
async ponentDidMount() {
await this.props.refreshExternalInfo();
this.setState({ externalInfoPresent: true });
if (this.props.externalInfo !== undefined && !this.state.infoSaved) {
await this.saveMyInfo();
}
}
async ponentDidUpdate(prevProps) {
if (prevProps.externalInfo === this.props.externalInfo || this.state.infoSaved) return;
await this.saveMyInfo();
}
async saveMyInfo() {
if (this.props.externalInfo === undefined || this.state.infoSaved) return;
// logic for saving stuff to external service
this.setState({ infoSaved });
}
// render and other stuff
}
saveMyInfo()
depends on externalInfo
being present.
I would like saveMyInfo()
to only be called once but it's being called twice with my current logic.
I would like to make sure that a function is called exactly one time, depending on some props and state.
class MyComponent extends Component {
state = {
externalInfoPresent: false,
infoSaved: false,
}
async ponentDidMount() {
await this.props.refreshExternalInfo();
this.setState({ externalInfoPresent: true });
if (this.props.externalInfo !== undefined && !this.state.infoSaved) {
await this.saveMyInfo();
}
}
async ponentDidUpdate(prevProps) {
if (prevProps.externalInfo === this.props.externalInfo || this.state.infoSaved) return;
await this.saveMyInfo();
}
async saveMyInfo() {
if (this.props.externalInfo === undefined || this.state.infoSaved) return;
// logic for saving stuff to external service
this.setState({ infoSaved });
}
// render and other stuff
}
saveMyInfo()
depends on externalInfo
being present.
I would like saveMyInfo()
to only be called once but it's being called twice with my current logic.
-
There's always a chance the ponent updates while
ponentDidMount
is still waiting forrefreshExternalInfo
orrefreshExternalInfo
causes the props to update and therefore causeponentDidUpdate
to be called. I'm not too clear as to what is exactly happening with this code because it's inplete but it is worth considering this – apokryfos Commented Jun 14, 2019 at 15:49 -
@apokryfos - yes, that is what is currently happening and I don't have a good solution for this:) I just added that
saveMyInfo()
depends onexternalInfo
being present which I omitted originally. – scuttle-jesuit Commented Jun 14, 2019 at 15:55 -
Does
refreshExternalInfo
change the props? If it does then maybe only keep the save inponentDidUpdate
– apokryfos Commented Jun 14, 2019 at 16:27 -
Yes,
refreshExternalInfo
can change the props. Not always though, only ifthis.props.externalInfo === undefined
and if I only keep it inponentDidUpdate
I can run into a situation whensaveMyInfo()
doesn't get call at all. – scuttle-jesuit Commented Jun 14, 2019 at 16:54
3 Answers
Reset to default 6If you want it to be called only once, then ponentDidMount is the place (it gets called exactly once in the lifecycle). Therefore you don't need it in ComponentDidUpdate (which gets called everytime a prop changes (after the initial render)!
Lifecycle: https://hackernoon./reactjs-ponent-lifecycle-methods-a-deep-dive-38275d9d13c0
Updated..
I think you Just need to set infosaved to true (this.setstate({infosaved:true}) after you call savemyinfo in ponentdidupdate.
Add an additional flag:
class MyComponent extends Component {
state = {
externalInfoPresent: false,
infoSaved: false,
saveMyInfoCalled: false,
}
async ponentDidMount() {
await this.props.refreshExternalInfo();
this.setState({ externalInfoPresent: true });
if (this.props.externalInfo !== undefined && !this.state.infoSaved) {
await this.saveMyInfo();
}
}
async ponentDidUpdate(prevProps) {
if (this.props.externalInfo !== undefined && !this.state.saveMyInfoCalled && !this.state.infoSaved) {
await this.saveMyInfo();
}
}
async saveMyInfo() {
this.setState({saveMyInfoCalled: true});
if (this.props.externalInfo === undefined || this.state.infoSaved) return;
// logic for saving stuff to external service
}
// render and other stuff
}
You probably should call this.setState({saveMyInfoCalled: false});
somewhere if external service fails. So saveMyInfo
doesn't get called several times simultaneously but has a second chance if something goes wrong.
class MyComponent extends Component {
async ponentDidMount() {
await this.props.refreshExternalInfo();
await this.saveMyInfo();
}
async ponentDidUpdate() {
await this.saveMyInfo();
}
async saveMyInfo() {
// if we don't have the info then skip for now
if (this.props.externalInfo === undefined || this.infoSaved) return;
// keep track that we already saved
this.infoSaved = true;
// perform save
}
}
本文标签:
版权声明:本文标题:javascript - Make sure function is called only once, either in componentDidMount or componentDidUpdate - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744228698a2596220.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论