Reputation: 1016
I want to try and use react to fetch data efficiently using useEffect appropriately.
Currently, data fetching is happening constantly, instead of just once as is needed, and changing when there is a input to the date period (calling different data).
The component is like this,
export default function Analytics() {
const {
sentimentData,
expressionsData,
overall,
handleChange,
startDate,
endDate,
sentimentStatistical,
} = useAnalytics();
return (
UseAnalytics is another component specifically for fetching data, basically just a series of fetches.
i.e.,
export default function useAnalytics() {
....
const { data: sentimentData } = useSWR(
`dashboard/sentiment/get-sentiment-timefilter?startTime=${startDate}&endTime=${endDate}`,
fetchSentiment
);
....
return {
sentimentData,
expressionsData,
overall,
handleChange,
setDateRange,
sentimentStatistical,
startDate,
endDate,
};
}
Thanks in advance,
The apirequest is like this,
export async function apiRequest(path, method = "GET", data) {
const accessToken = firebase.auth().currentUser
? await firebase.auth().currentUser.getIdToken()
: undefined;
//this is a workaround due to the backend responses not being built for this util.
if (path == "dashboard/get-settings") {
return fetch(`/api/${path}`, {
method,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: data ? JSON.stringify(data) : undefined,
})
.then((response) => response.json())
.then((response) => {
if (response.error === "error") {
throw new CustomError(response.code, response.messages);
} else {
return response;
}
});
}
return fetch(`/api/${path}`, {
method,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: data ? JSON.stringify(data) : undefined,
})
.then((response) => response.json())
.then((response) => {
if (response.status === "error") {
// Automatically signout user if accessToken is no longer valid
if (response.code === "auth/invalid-user-token") {
firebase.auth().signOut();
}
throw new CustomError(response.code, response.message);
} else {
return response.data;
}
});
}
I think using useEffect here is the right approach. i.e.,
useEffect(()=>{
// this callback function gets called when there is some change in the
// state variable (present in the dependency array)
},[state variable])
I'm confused about how to update the constants properly, something like this seems like one approach, but not sure about how I can use useEffect to update these variables properly, or if I should be doing this inside of useAnalytics?
i.e.,
const [analytics, setAnalytics] = useState({
sentimentData: {},
expressionsData: {},
overall: {},
handleChange: () => {},
startDate: '',
endDate: '',
sentimentStatistical:{},
});
useEffect(()=>{
// this callback function gets called when there is some change in the
// state variable (present in the dependency array)
},[state variable])
const {
sentimentData,
expressionsData,
overall,
handleChange,
startDate,
endDate,
sentimentStatistical,
} = useAnalytics();
Realised SWR is a hook, need to use SWR documentation :P
Upvotes: 0
Views: 99
Reputation: 134
You have to store the requested information in states inside your custom hook. Then you could consume this hook wherever you want. This should work.
const useAnalitycs = () => {
const [analytics, setAnalytics] = useState({
sentimentData: {},
expressionsData: {},
overall: {},
startDate: '',
endDate: '',
sentimentStatistical:{},
});
const handleChange = () => {
/* */
};
useEffect(() => {
const fetchData = async () => {
// const response = await apiCall();
// setAnalytics(...)
};
fetchData();
}, []); // called once
return {
...analytics,
handleChange
};
};
const ComponentConsumerA = () => {
/*
const { state/methods you need } = useAnalytics()
...
*/
};
const ComponentConsumerB = () => {
/*
const { state/methods you need } = useAnalytics()
...
*/
};
Upvotes: 2