I have 2 reactjs files:
- Reports.js (used to request report and display the result)
- AuthContext.js (has a socket connection to maintain communication with the backend server)
user first goes to the report page generated by Reports.js and then there is a call to the backend server which returns right away but it shows a loading spinner. When the report is completed, it will send the data to AuthContext.js. However, I have trouble from AuthContext.js to be able to request a call setReportLoading() in Reports.js for the purpose of stopping the loading spinner. can you please advise how to solve this ?
I tried the method below setReportLoading() but it has this error:
setReportLoading.js:115 Uncaught TypeError: setReportLoading is not a function
here is my code snippet
In file AuthContext.js
import { setReportLoading } from 'Reports';
export const AuthProvider = ({ children }) => {
socket.on('processmessage', (msg) => {
if (msg.type == 'checking'){
setReportLoading(2);
}
});
}
In file Reports.js
const Reports = () => {
const [loading, setLoading] = useState(1)
const setReportLoading = (isLoading) => {
setLoading(isLoading);
};
const renderContent = () => {
if (loading === 1) return (
<div className="d-flex justify-content-center align-items-center" style={{ minHeight: '200px' }}>
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">{t('loc_react_loading')}</span>
</div>
</div>
)
if (loading === 2) return (
<div className="mb-4 card border-0 shadow-sm" style={{'min-width': '900px'}}>
{renderReportSelection()}
{showReport && renderReport()}
</div>
)
}
return (
<DashboardLayout>
</DashboardLayout>
)
}
export default Reports;
UPDATE tried using jotai 2.0.0 but somehow no crash, but it didnt seem to go to handleReportloadingChange() function
in AuthContext.js
import { atom, useAtom } from 'jotai';
export const reportloadingAtom = atom(1);
export const AuthProvider = ({ children }) => {
const [reportloading, setReportloading] = useAtom(reportloadingAtom);
socket.on('processmessage', (msg) => {
if (msg.type == 'checking') {
setReportloading(2);
}
});
// ...
};
in Reports.js
import { useAtom } from 'jotai';
import { reportloadingAtom } from 'AuthContext'
const Reports = () => {
const [reportloading, setReportloading] = useAtom(reportloadingAtom);
const [loading, setLoading] = useState(1);
useEffect(() => {
// This function will run every time the value of reportloadingAtom changes
function handleReportloadingChange() {
console.log("handleReportloadingChange")
setLoading(reportloading);
}
}, [reportloading]);
// ...
};
2
Answers
I dont think you can export or import a function declared inside a React component without a third party lib. What you can do is pass it as a props to a child component.
Given the code you have shared, I would sugest you refactor your AuthProvider to a regular function, and not a React component. I suggest this because I dont see your AuthProvider as a child of your Reports component. You can then call this function within your Reports component and have it return some value to then change the vaue of your loading.
It seems like you are trying to use Jotai to manage state between components. In your Jotai-based solution, you’ve created an atom
reportloadingAtom
to manage the loading state and attempted to use it in bothAuthContext.js
andReports.js
. However, there are some issues in your implementation.AuthContext.js
Reports.js
Here are some improvements:
===
for strict equality comparison.Reports.js
; Jotai will handle it.Ensure that both components are wrapped with the
JotaiProvider
at the highest level of your component tree. If you haven’t done so, you can use it like this:This should help in managing the loading state between your components using Jotai. If you still face issues, consider checking the console for any error messages or log statements that might provide more information about what’s going wrong.