简体   繁体   中英

How do I update an existing state object without infinite redirects?

const useExample = (something) => {
   const [v, setV] React.useState(something)
   React.useEffect(() => setV({...v ...something), [something, v, setV])
}

This code above runs an infinite loop because I am using v to set v . How can I set v to a value using v but not cause this loop?

The second argument in the useEffect handles the rerendering of the function. The answer to your question since it is quite generic would be to use an empty array.

const useExample = (something) => {
   const [v, setV] React.useState(something)
   React.useEffect(() => setV({...v ...something), [])
}

But that depends on the condition you want to set... Tell you the truth, I am kinda confused about your case. Could you give more info...??

The example you are giving is quite problematic. Why are you spreading the initalValue?? And why would you set the v as the rerendering option??

The pattern used is to have a flag to do the update whenever you need that change to occur.

  const [v, setV] = React.useState(something)
  const [flagV, setFlagV] = React.useState(something)
   React.useEffect(() => {
      if (flagV){ 
       setV({...v ...something);
       setFlagV(false)
         }
}, [something,v,setV,flagV,setFlagV])

I suspect there may be a better solution to your problem if I know why you'd combine props with state.

It looks like you're trying to create a function that combines the argument previously passed to it with the argument currently passed to it letting current override last properties. If that is the case then there is a much simpler way of doing this.

With the information provided so far you can prevent the infinite loop by memoizing props (called something in your method) and v and have that memoized function set the merged result:

import React, { useState, useMemo } from 'react';

const Something = something => {
  const [v, setV] = useState(something);
  //memoize setting merged
  const merged = useMemo(() => {
    return { ...v, ...something };
  }, [something, v]);
  return (
    <div>
      {JSON.stringify(merged)}
      {/* can still set v  */}
      <button onClick={() => setV({ other: 22 })}>
        Add other
      </button>
    </div>
  );
};
export default () => {
  const [p, setP] = useState(1);
  return (
    <div>
      {/* change the props passed to Something */}
      <button onClick={() => setP(p + 1)}>UP</button>
      <Something prop={p} />
    </div>
  );
};

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