admin管理员组文章数量:1419573
Can someone help me solve how do I setState inside ponentDidUpdate
and not have an infinite loop? Some suggestions said to have a conditional statement, but I am not too familiar with how do I set the conditional for my code.
This is what my code looks like:
I have a dashboard ponent that gets all the panies and projects data from external functions where the fetch happens and then updates the state. The projects are associated with the pany's id.
I am able to get the list of all the projects in JSON, but I can't figure out how to update my projects state inside ponentDidUpdate once rendered.
CompanyDashboard.js
import { getCompanys } from "../../actions/panyActions";
import { getProjects } from "../../actions/projectActions";
class CompanyDashboard extends Component {
constructor(props) {
super(props);
this.state = {
panies: [],
projects: []
};
}
ponentWillMount() {
// get all panies and update state
getCompanys().then(panies => this.setState({ panies }));
}
ponentDidUpdate(prevState) {
this.setState({ projects: this.state.projects });
}
render() {
const { panies, projects } = this.state;
{
panies.map(pany => {
// get all the projects
return getProjects(pany);
});
}
return <div />;
}
}
export default CompanyDashboard;
panyActions.js
import { getUser, getUserToken } from './cognitoActions';
import config from '../../config';
export function getCompanys() {
let url = config.base_url + '/panys';
return fetch(url, {
method: 'GET',
headers: {'token': getUserToken() }
})
.then(res => res.json())
.then(data => { return data })
.catch(err => console.log(err));
}
projectActions.js
import { getUserToken } from './cognitoActions';
import config from '../../config';
export function getProjects(pany) {
let url = config.base_url + `/panys/${pany._id['$oid']}/projects`;
return fetch(url, {
method: 'GET',
headers: {'token': getUserToken() }
})
.then(res => res.json())
.then(data => { return data })
.catch(err => console.log(err));
}
Can someone help me solve how do I setState inside ponentDidUpdate
and not have an infinite loop? Some suggestions said to have a conditional statement, but I am not too familiar with how do I set the conditional for my code.
This is what my code looks like:
I have a dashboard ponent that gets all the panies and projects data from external functions where the fetch happens and then updates the state. The projects are associated with the pany's id.
I am able to get the list of all the projects in JSON, but I can't figure out how to update my projects state inside ponentDidUpdate once rendered.
CompanyDashboard.js
import { getCompanys } from "../../actions/panyActions";
import { getProjects } from "../../actions/projectActions";
class CompanyDashboard extends Component {
constructor(props) {
super(props);
this.state = {
panies: [],
projects: []
};
}
ponentWillMount() {
// get all panies and update state
getCompanys().then(panies => this.setState({ panies }));
}
ponentDidUpdate(prevState) {
this.setState({ projects: this.state.projects });
}
render() {
const { panies, projects } = this.state;
{
panies.map(pany => {
// get all the projects
return getProjects(pany);
});
}
return <div />;
}
}
export default CompanyDashboard;
panyActions.js
import { getUser, getUserToken } from './cognitoActions';
import config from '../../config';
export function getCompanys() {
let url = config.base_url + '/panys';
return fetch(url, {
method: 'GET',
headers: {'token': getUserToken() }
})
.then(res => res.json())
.then(data => { return data })
.catch(err => console.log(err));
}
projectActions.js
import { getUserToken } from './cognitoActions';
import config from '../../config';
export function getProjects(pany) {
let url = config.base_url + `/panys/${pany._id['$oid']}/projects`;
return fetch(url, {
method: 'GET',
headers: {'token': getUserToken() }
})
.then(res => res.json())
.then(data => { return data })
.catch(err => console.log(err));
}
Share
Improve this question
edited Dec 30, 2019 at 12:03
Afia
6835 silver badges17 bronze badges
asked Jul 18, 2018 at 19:08
SamWhiteSamWhite
893 silver badges12 bronze badges
4 Answers
Reset to default 1The following code is not doing anything meaningful. You are setting your state.projects to be equal to your state.projects.
ponentDidUpdate() {
this.setState({ projects: this.state.projects })
}
Also, the following code is not doing anything meaningful because you are not saving the result of panies.map anywhere.
{
panies.map((pany) => {
return getProjects(pany)
})
}
It's hard to tell what you think your code is doing, but my guess is that you think that simply calling "panies.map(....) " inside your render function is going to TRIGGER the ponentDidUpdate function. That is not how render works, you should go back to the drawing board on that one. It also looks like you think that using the curly brackets {} inside your render function will display the objects inside your curly brackets. That's also not true, you need to use those curly brackets inside the ponents. For instance: {projects}
If I had to guess... the following code is how you actually want to write your ponent
import { getCompanys } from '../../actions/panyActions';
import { getProjects } from '../../actions/projectActions';
class CompanyDashboard extends Component {
constructor(props) {
super(props);
this.state = {
panies: [],
projects: []
}
}
ponentWillMount() {
getCompanys().then(panies => {
const projectPromises = panies.map((pany) => {
return getProjects(pany)
});
Promise.all(projectPromises).then(projects => {
//possibly a flatten operator on projects would go here.
this.setState({ panies, projects });
});
/*
* Alternatively, you could update the state after each project call is returned, and you wouldn't need Promise.all, sometimes redux can be weird about array mutation in the state, so look into forceUpdate if it isn't rerendering with this approach:
* const projectPromises = panies.map((pany) => {
* return getProjects(pany).then(project => this.setState({projects: this.state.projects.concat(project)}));
* });
*/
)
}
render() {
const { panies, projects } = this.state;
//Not sure how you want to display panies and projects, but you would
// build the display ponents, below.
return(
<div>
{projects}
</div>
)
}
}
export default CompanyDashboard;
ponentDidUpdate
has this signature, ponentDidUpdate(prevProps, prevState, snapshot)
This means that every time the method gets called you have access to your prevState
which you can use to pare to the new data, and then based on that decide if you should update again. As an example it can look something like this.
ponentDidUpdate(prevProps, prevState) {
if (!prevState.length){
this.setState({ projects: this.state.projects })
}
}
Of course this is only an example since I don't know your requirements, but this should give you an idea.
When
ponentDidUpdate()
is called, two arguments are passed:prevProps
andprevState
. This is the inverse ofponentWillUpdate()
. The passed values are what the values were, andthis.props
andthis.state
are the current values.
`ponentDidUpdate(prevProps) {
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}`
You must check the state/props if new state/props different from previous one then you can allow to update your ponent.
You may call
setState()
immediately inponentDidUpdate()
but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop. It would also cause an extra re-rendering which, while not visible to the user, can affect the ponent performance. If you’re trying to “mirror” some state to a prop ing from above, consider using the prop directly instead.
This is because ponentDidUpdate is called just after a ponent takes up somechanges in the state. so when you change state in that method only then it will move to and from from that method and state change process
本文标签: javascriptReact setState inside componentDidUpdate causing infinite loopStack Overflow
版权声明:本文标题:javascript - React setState inside componentDidUpdate causing infinite loop - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745312354a2652991.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论