admin管理员组

文章数量:1435859

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 previous setState? And why have tracked and untracked 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
Add a ment  | 

2 Answers 2

Reset to default 4

As 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:

  1. It's not clear why you're calling setState again in the pletion handler of the outer setState.

  2. It's not clear why you have tracked and untracked 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

本文标签: javascriptSetState using the foreach loop does not workStack Overflow