Matt Brody
Matt Brody

Reputation: 1513

setState never gets set in useEffect after API call responds with data

I'm trying to update state immediately after data comes in from the API. The data is coming in, I can see it using the console.log right below my API request. All of the data is right but for some reason, setState never sets in my hook. It just returns and empty array even after the console displays data.

const [experienceData, setExperienceData] = useState([]);

const { match = {} } = props;

    useEffect(() => {
        async function fetchData() {
            if (Object.keys(match.params).length > 0) {
                const response = await ApiService.getExperiences(match.params.experieneId);
                console.log(response)
                setExperienceData(response)
            }
        }
        fetchData();
    }, []);

I must be doing something wrong but I can't figure out what that is. Hoping someone on here has run into the same issue.

UPDATE: I just changed everything over the a class and duplicated the exact code on another file and ran into the exact same issue. The console updates with the data, but the setState on the line immediately after the data does not setState.

async componentDidMount() {
        if (Object.keys(this.props.match.params).length > 0) {
            const response = await ApiService.getExperiences(this.props.match.params.experieneId);
            console.log(response[0])
            this.setState({ experienceData: response[0], occurrenceData: response[0].occurrences });
        }
    }

Upvotes: 1

Views: 74

Answers (4)

Hema Ramasamy
Hema Ramasamy

Reputation: 716

You have to useSetState in a proper way, the issue is in the setExperienceData

const [experienceData, setExperienceData] = useState({response:""});

const { match = {} } = props;

useEffect(() => {
    async function fetchData() {
        if (Object.keys(props.match.params).length > 0) {
            const response = await ApiService.getExperiences(match.params.experieneId);
            console.log(response)
            setExperienceData(experienceData => ({ ...experienceData, response: response }));
        }
    }
    fetchData();
}, []);
return(<div>check {experienceData.response}</div>)

Upvotes: 1

nishkaush
nishkaush

Reputation: 1548

Could you please try passing [match.params] as the second argument to your useEffect.

Upvotes: 0

michael
michael

Reputation: 4173

const [experienceData, setExperienceData] = useState([]);

const { match = {} } = props;

useEffect(() => {
  fetchData();
}, [props.match.params]);

const async fetchData = () => {
  if (Object.keys(match.params).length > 0) {
    const response = await ApiService.getExperiences(match.params.experieneId);
    console.log(response)
    setExperienceData([...response])
  }
}

Upvotes: 0

Victor Oliveira
Victor Oliveira

Reputation: 393

I see you left the dependency array empty. This tells React to run this effect only once: when the component first renders. If you want your useEffect to respect your state hook, put setExperienceData inside the dependency array

Upvotes: 0

Related Questions