GregHouse
GregHouse

Reputation: 315

Setting state after data load on useEffect

Attempting to update state after data load on useEffect. Able to update a local variable but not state. I am following an example from https://www.robinwieruch.de/react-hooks-fetch-data/ where Robin sets state in a similar way. For some reason, the state variable is never set correctly in my case.

Using AWS Amplify to load graphQL data. Seems to work successfully for local variable but not state variable.

const [serviceTypes, setServiceTypes] = useState([{}]);
let myServiceTypes = [{}]; // try it with a local variable to debug

useEffect(() => {
  let unmounted = false;

  async function fetchData() {
    const result = await API.graphql(
      graphqlOperation(queries.listServiceTypes)
    );
    console.log(result);
    console.log('setting service types...');
    console.log(result.data.listServiceTypes.items);
    setServiceTypes(result.data.listServiceTypes.items);
    myServiceTypes = result.data.listServiceTypes.items;
    console.log(myServiceTypes); // set correctly
   console.log(serviceTypes); // empty
  }
  if (!unmounted) {
    fetchData();
  }
  return () => {
    unmounted = true;
  };
}, []); 

Expecting serviceTypes to be set to the data loaded. Instead it is empty.

Upvotes: 0

Views: 2077

Answers (2)

Jake Luby
Jake Luby

Reputation: 1758

It's because you aren't thinking about the effect and renders correctly.

Mounting/Render 1

  • fetchData is called
  • setServiceTypes and passes the service type to the next render
  • serviceTypes is empty

Render 2

  • useEffect is not called
  • serviceTypes is now what the previous serviceTypes was set to

Try logging out the serviceTypes right before the render/return

Upvotes: 0

tgreen
tgreen

Reputation: 1926

setState does not work synchronously like that. You cannot expect your serviceTypes variable to immediately contain the data right after you set it. It will be updated when the component re-renders. try moving the console.log(serviceTypes); outside of the useEffect.

see https://stackoverflow.com/a/36087156/5273790 for an explanation of setState async.

Upvotes: 1

Related Questions