Search code examples
reactjsreact-hooksuse-effectuse-statesetstate

React Can Not SetState After Fetch


I have a component, where i want to render some data after it is successfully fetched, but the SetState Wont Work even after a successful fetch. Even a 'console.log(response.data)' is showing the right object, but Why the 'setGroupData(response.data)' line below it wont change the state?, but returning an empty object instead.

here is the code :

const GroupContent = ({ groupContent, changeGroupTitle }) => {
  const groupId = window.location.href.split(
    "http://localhost:3001/groups/"
  )[1];
  const [groupData, setGroupData] = useState({});
  let token = "";

  const getGroupData = async () => {
    token = await localStorage.getItem("token");

    if (token) {
      try {
        const auth = `Bearer ${token}`;
        // console.log(auth);
        const response = await axios.get(`/api/groups/${groupId}`, {
          headers: {
            Authorization: auth,
          },
        });
        console.log(response.data);
        setGroupData(response.data);
        console.log(groupData);
        changeGroupTitle(groupData.title);
      } catch (err) {
        console.log(err.response);
      }
    }
  };

  useEffect(() => {
    getGroupData();
  }, []);

Solution

  • The setState is working fine but the update is asynchronous in nature. You can do couple of things here

    1. Convert setGroupData(response.data) to setGroupData(() => ({...response.data}})

    2. Listen to state change using useEffect with groupData in the depenency array.

    Here's some other things which I'd change if I were you:

    • Local Storage or session storage operations are not asynchronous. I'd remove the await before the localStorage operation
    • I'd rename the function getGroupData to something else that is less confusing, eg. fetchGroupData

    But these are my personal preferences, the first two pointers will work