简体   繁体   中英

how to update an object using useEffect in Reactjs and Typescript

I am very new to Reactjs + Typescript and i am trying to figure out why i am getting the error below.

React 16.9

const STEP_STATUS = {
  COMPLETED: "Completed",
  INCOMPLETE: "Incomplete",
};

const Foo = () => {
  const [state, setState] = useState({
    step: 1,
    firstName: '',
    lastName: '',
    status: STEP_STATUS["INCOMPLETE"],
  });

const nextStep = () => {
    setState({...state, step: state.step + 1});
  }

useEffect(() => {
    if (state.step + 1 !== state.step) {
      // setState(prev => {...prev, state.step = STEP_STATUS["COMPLETED"]}); // I tried this too
      setState(...state, state.status = STEP_STATUS["COMPLETED"]);
    } else {
      console.log("error");  // don't mind this line
    }
  }, [state]);

I am trying to create a side effect using useEffect , after pressing the button nextStep (which brings the user to the next page), I want to update the status of current page to "Completed" before we get to the next page.

I might really be doing this wrong.

Any help would be very helpful.

current error

×
TypeError: state is not iterable
  53 | useEffect(() => {
  54 |   if (state.step + 1 !== state.step) {
  55 |     // setState(prev => {...prev, state.step = STEP_STATUS["COMPLETED"]});
> 56 |     setState(...state, state.status = STEP_STATUS["COMPLETED"]);
     | ^  57 |   } else {
  58 |     console.log("error");
  59 |   }

You need to put object braces around the call of setState as follow:

setState({...state, status: STEP_STATUS["COMPLETED"]})

also it's recommended to update using the prevState values passed to setState in order to prevent clousers.

I don't think it is a good idea to use the entire state as the dependency array on the useEffect hook. This will actually lead to an inifinite loop at the updating of state within the useEffect hook will result it to be triggered over and over again.

Looking at what you are trying to achieve, I believe state.step should be on the dependency array instead. In addition, you are using the wrong syntax for referencing properties within an object. Instead of using equal ( = ), you should be using the colon( : ) instead.

useEffect(() => {
  setState({
    ...state,
    status: STEP_STATUS["COMPLETED"]
  });
}, [state.step]);

If you are trying to make use of the callback within setState instead, you can modify to this:

setState((prevState) => ({
  ...prevState,
  status: STEP_STATUS["COMPLETED"]
})); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM