I am trying to update the state using the following code:
handleCheckBox = () => {
this.setState(({isCheckd}) => ({isCheckd: !isCheckd, isEnable: !isCheckd}), () =>
this.props.untracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd })),
this.props.tracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd }))
);
}
When I try to update using the forEach
function. In the first loop the state gets updated as you see the conditons are the same. but in this first one gets change but second for each does not get change. If I change the order in which they are written then the whichever is first it's state gets changed but not the second one.
handleTableCheckboxChange = (e, type) => {
this.setState({
[e.target.name]: e.target.checked
}, () => {
const checkedItems = this.props[type].filter((item) => this.state[item.resumeId])
this.setState({
isCheckd: checkedItems.length === this.props[type].length ? true : false,
isEnable: checkedItems.length > 1 ? true : false
});
});
}
How can I prevent this from happening?
I am trying to update the state using the following code:
handleCheckBox = () => {
this.setState(({isCheckd}) => ({isCheckd: !isCheckd, isEnable: !isCheckd}), () =>
this.props.untracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd })),
this.props.tracked.forEach((item) => this.setState({ [item.resumeId]: this.state.isCheckd }))
);
}
When I try to update using the forEach
function. In the first loop the state gets updated as you see the conditons are the same. but in this first one gets change but second for each does not get change. If I change the order in which they are written then the whichever is first it's state gets changed but not the second one.
handleTableCheckboxChange = (e, type) => {
this.setState({
[e.target.name]: e.target.checked
}, () => {
const checkedItems = this.props[type].filter((item) => this.state[item.resumeId])
this.setState({
isCheckd: checkedItems.length === this.props[type].length ? true : false,
isEnable: checkedItems.length > 1 ? true : false
});
});
}
How can I prevent this from happening?
Share Improve this question edited Apr 24, 2019 at 9:38 ganesh kaspate asked Apr 24, 2019 at 9:13 ganesh kaspateganesh kaspate 2,69512 gold badges52 silver badges105 bronze badges 5-
1
It's not clear what you're asking here. Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the
[<>]
toolbar button). Stack Snippets support React, including JSX; here's how to do one. – T.J. Crowder Commented Apr 24, 2019 at 9:16 - 1 Although you can call setState in a loop, IMHO is better to collect in the loop all the changes and apply a sigle setState after the loop. – Mosè Raguzzini Commented Apr 24, 2019 at 9:17
- 1 Doing multile setState() in one loop is not remended, since it will re-render the site every time setState is called. It is better do a forEach to collect all the data you need and call one setState to apply the changes. – TeaNyan Commented Apr 24, 2019 at 9:18
-
Why are you doing
setState
in the pletion handler of a previoussetState
? And why havetracked
anduntracked
when you're doing the same thing with both? – T.J. Crowder Commented Apr 24, 2019 at 9:20 - Actually both are the diff tables.so both are having the diff data – ganesh kaspate Commented Apr 24, 2019 at 9:28
2 Answers
Reset to default 4As I said in ments on your previous question, you're breaking one of the fundamental rules of React: If you're setting state based on existing state, you must use the callback version of setState
, not the version you pass an object into.
Looking at that code, doing so would look something like this:
handleCheckBox = () => {
this.setState(
({isCheckd}) => ({isCheckd: !isCheckd, isEnable: !isCheckd}),
() => this.setState(({isCheckd}) => {
const newState = {};
for (const item of [...this.props.untracked, ...this.props.tracked]) {
newState[item.resumeId] = isCheckd;
}
return newState;
})
);
}
But, a couple of odd things jump out:
It's not clear why you're calling
setState
again in the pletion handler of the outersetState
.It's not clear why you have
tracked
anduntracked
when you're doing the same thing with them.
If you can do it in one state update, that would probably be better:
handleCheckBox = () => {
this.setState(({isCheckd}) => {
const newState = {
isCheckd: !isCheckd,
isEnable: !isCheckd
};
for (const item of [...this.props.untracked, ...this.props.tracked]) {
newState[item.resumeId] = isCheckd;
}
return newState;
});
}
Re your updated question, handleTableCheckboxChange
has the same problem (setting state based on existing state passing an object into setState
) and thus the same solution (use the callback version) applies:
handleTableCheckboxChange = ({target: {name, checked}}, type) => {
this.setState(prevState => {
const newState = {[name]: checked};
const checkedItems = this.props[type].filter((item) => prevState[item.resumeId]);
newState.isCheckd = checkedItems.length === this.props[type].length;
newState.isEnable = checkedItems.length > 1;
return newState;
});
};
(Notice I've removed the ? true : false
from the lines setting isCheckd
and isEnable
. ===
and >
already give you a boolean, there's no point served by adding a conditional operator there.)
Hey I'm facing same problem recently.but I got the solution.
const [data,setData] = useState([]);
const emails = ["127","hello1","here"];
emails.forEach((email)=>{
setData((prev) => [...prev,emial])
})
Above code gives me an error
Too many re-renders. React limits the number of renders to prevent an infinite loop.
Solution
const [data,setData] = useState([]);
const emails = ["127","hello1","here"];
useEffect(()=>{
emails.forEach((email)=>{
setData((prev) => [...prev,emial])
})
},[])
Put forEach or map inside useEffect for avoiding the error and state will also update
May be this answer helps some who facing same error
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745670403a4639369.html
评论列表(0条)