Even if a state has been changed, but the view has not been rendered again in React / Next.js. Here is my code and console.log result.
As a prerequisite, I think I understand the behavior of useState, useEffect, Promise, and async/await, but I couldn't figure it out any more on my own.
The return value of GetGithubData is Promise, so I'm wondering if that's the reason why the update doesn't run simply because I can't access the object inside. However, if that is the case, in order to resolve Promise, I have to add "await", and in order to do so, I have to change to the function to "async" function, and when I change it to the async function, I get an error if the "return" returns an object, and the radar chart is not displayed in the first place.
Can someone please tell me how to fix this? I've seen a few similar questions, but none of them seemed to fit.
Radarchart.tsx code is below, which is a component drawing a radarchart graph like this. And this graph itself is successfully drawn in my browser but the number of commit to Github is still 20 instead of 12, which means the result of useEffect is not rendered again.
import React, { useEffect, useState } from "react";
import {
Chart,
LineElement,
PointElement,
RadialLinearScale,
} from "chart.js";
import { Radar } from "react-chartjs-2";
import GetGithubData from "../services/githubService";
const RadarChart = () => {
const [githubData, setGithubData] = useState({});
useEffect(() => {
setGithubData(GetGithubData());
}, []);
const randomNumber1 = githubData["total"] ? githubData["total"] : 20;
console.log(githubData);
console.log(randomNumber1);
const randomNumber2 = 35;
const randomNumber3 = 45;
const randomNumber4 = 75;
const randomNumber5 = 85;
const data = {
datasets: [
{
data: [
randomNumber1,
randomNumber2,
randomNumber3,
randomNumber4,
randomNumber5,
],
backgroundColor: "rgba(255, 99, 132, 0.2)",
borderColor: "rgba(255, 99, 132, 1)",
},
],
};
Chart.register(
LineElement,
PointElement,
RadialLinearScale,
);
return <Radar data={data} options={options} />;
};
export default RadarChart;
githubService.tsx is a service file to fetch data that I want to fetch from Github API.
const GetGithubData = async () => {
const owner = "aaaa";
const repo = "bbbb";
const url = `https://api.github.com/repos/${owner}/${repo}/stats/contributors`;
const response = await fetch(url);
const data = await response.json();
return data[0];
};
export default GetGithubData;
The result of console.log are below.
GetGithubData
is an async
function, meaning it implicitly returns a Promise. You are saving the Promise object into the githubData
state.
useEffect(() => {
setGithubData(GetGithubData());
}, []);
You are correct that you need to await it resolving.
You can chain from the returned promise and call setGithubData
in the .then
block with the returned value:
useEffect(() => {
GetGithubData()
.then(data => {
setGithubData(data);
});
}, []);
Or create an async
function in the useEffect
hook and await
the value.
useEffect(() => {
const getGitHubData = async () => {
const data = await GetGithubData();
setGithubData(data);
};
getGitHubData();
}, []);