简体   繁体   中英

Do functions get the latest state value in React?

I have a function inside of my functional component that uses a value saved in state. However, when it is called, it has the original value in state, not the updated value. When I look at my component in Chrome React Dev Tools, I see that the updated value is stored in state. Aren't functions supposed to get the latest state value in React? I didn't think I'd have to wrap my functions in a useEffect every time some value in state they depend on changes. Why is this happening?

const Editor = (props) => {
  const [template, setTemplate] = useState(null);
  const [openDialog, setOpenDialog] = useState(false);

  useEffect(() => {
   if (props.templateId) {
     getTemplate(props.templateId));
   }
  },[]);

  const getTemplate = (templateId) => {
    {...make API to get template...}
    .then((response) => {
      if (response.template) setTemplate(response.template);
    });
  }

  /* THIS FUNCTION SAYS TEMPLATE IS ALWAYS NULL */
  const sendClick = async () => {
    if (template) {
      await updateTemplate();
    } else {
      await initializeTemplate();
    }
    setOpenDialog(true);
  };

}

UPDATE: I figured out the issue. The sendClick function is being used inside an object that I have in state. When that object is created, it creates a version of the sendClick function based on the state at that time. I realized I needed to refactor my code so that the function is not stored within my object in state so that the function will always have the latest state values.

Please correct the code there its setTemplate(template)); not getTemplate(template)); I'm guessing that you have that right in the source code... if Yes then,

You have got into a trap that all developers new to React fall into.

This code is betraying you ...

 useEffect(() => {
   if (props.template) {
     setTemplate(template)); // Mentioned as getTemplate(template));
   }
  },[]); // Here is where you make the mistake

The second argument you pass to the useEffect is called as Dependencies . Meaning if your useEffect is dependent on any state or any variable or function, Ii should be pass as the second argument inside the [] . By now you should have got the answer.

Clearly, your useEffect is dependent on template . You should pass that inside the [] .

So the code will be : -

 useEffect(() => {
   if (props.template) {
     setTemplate(template)); // Mentioned as getTemplate(template));
   }
  },[template]);

Now React will automatically run the function every time the value of template changes therefore, updates template .

For more information about useEffect ...

Refer React Documentation

Refer the useEffect API

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