简体   繁体   中英

ReactJS component won't update after first API call

So I recently started to discover ReactJS. I have a simple Spring Boot api which has a few methods. One of these returns a list of objects. I get these in my frontend by using Axios to make the HTTP call.

export function getItems() {
  const [items, setItems] = useState([]);
  useEffect(async () => {
    await client.get('items').then((result) => {
      setItems(result.data);
    });
  }, []);
  return items;

The items are mapped in a gallery component and shown on screen. Next to this, I have an addItem function which posts an item object obtained through a form to my api.

export async function addPet(newPet) {
      await client.post(
        '/pets',
        newPet,
      );
    }

My AddPet component is loaded inside my Gallery component. The form is shown on the right side of the screen and when I click the "Add Item" button, I want the item to be added and my list of items reloaded to show the newly added item. Right now, I can not get this working in a correct way. If I remove the "[]" from the final part of my useEffect() in my getItems() functions, everything seems to work but in reality the app is making the getItems call over and over again. If I add "[]", the call is only made once at the start, but will not re-render the gallery component when an item is added. The handleSubmit() for my "Add item" button is as follows:

const handleSubmit = () => {
    const newItem = new Item();
    newItem .name = formValue.name;
    newItem .image = formValue.image;
    newItem .pitemText = formValue.itemText;
    addItem(newItem);
  };

So my question here is: how can I get that gallery component to re-render whenever I add a new item or delete one of the items? I figure I need a way to change the state of the component but I can't seem to get it done.

The second parameter of useEffect (the Array ) has an important role: the items in that array trigger the useEffect to re-run.

Some cases:

  • useEffect(() => {}, []) : runs once, after the component is mounted
  • useEffect(() => {}, [var1, var2,..., varn]) : runs when var1 or var2 or varn is updated
  • useEffect(() => {}) : runs on every completed re-render (default behavior)

More on useEffect : useEffect hook

So, your code works as expected:

useEffect(async () => {
  await client.get('items').then((result) => {
    setItems(result.data);
  });
}, []); // -> runs once, when component is mounted

you need to organize your code in such a way, that this useEffect hook can run on the update of the variable whose change you want to watch.

dont pust async as the first parameter of useEffect hook as below, wont work well

useEffect(async () => {
  await client.get('items').then((result) => {
    setItems(result.data);
  });
}, []);

instead you can use external function or IIEF function as below

useEffect(() => {
  (async () => {
    await client.get('items').then((result) => {
     setItems(result.data);
    });
  })()
  
}, []);

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