I have a socket connection to a component, but its data is used in various other components. To reduce the complexity I try to use contextAPI to share content among all other components.
Here is my socket connection code
var NotificationData="";
useEffect(() => {
if(!state.id){
return
}
var token = ((localStorage.getItem("provider__token"))?
localStorage.getItem("provider__token"): sessionStorage.getItem("provider__token")) || ''
let io=new WebSocket(
process.env.REACT_APP_BACKEND_DEVELOPMENT_URL_SOCKET
'ws/provider_notifications/'
state.id
'/'
);
io.onopen = (e) => {
io.send(JSON.stringify({'token':token}))
}
io.onmessage = (e) => {
let data=JSON.parse(e.data);
NotificationData=React.createContext(data);
if(data.type && data.type === 'notification'){
setStatus(true);
setTotalNotification(data.notifications_unread)
}
};
})
But this way I can't able to export my context. I checked some example which has the following syntax.
export const UserContext = React.createContext(userContextTemplate)
But this example only works with static data.
Please suggest what I do to make this context data available in another component.
CodePudding user response:
Create context.js
file
import { createContext, useContext, useState } from 'react'
//create a context
const NotificationData = createContext({})
export default NotificationData
//create a provider of that context that will provide values
//which can be used by all the children conponents
export const NotificationDataProvider = ({ children }) => {
const [notificationData, setNotificationData] = useState(null)
return (
<NotificationData.Provider value={{ notificationData, setNotificationData }}>
{children}
</NotificationData.Provider>
)
}
//create a helper custom hook to used by other components who
//wish to use the context values
export const useNotificationDataContext = () => {
const { notificationData, setNotificationData } = useContext(NotificationData)
return {
notificationData,
setNotificationData
}
}
Your Socket file where the data will get set
...
//get the context value which will set the notification data
const { setNotificationData } = useNotificationDataContext()
useEffect(() => {
if (!state.id) {
return;
}
var token =
(localStorage.getItem("provider__token")
? localStorage.getItem("provider__token")
: sessionStorage.getItem("provider__token")) || "";
let io = new WebSocket(
process.env.REACT_APP_BACKEND_DEVELOPMENT_URL_SOCKET
"ws/provider_notifications/"
state.id
"/"
);
io.onopen = (e) => {
io.send(JSON.stringify({ token: token }));
};
io.onmessage = (e) => {
let data = JSON.parse(e.data);
//After getting the data set it using the setNotificationData.
//This will set the state in the provider and will re-render all
//the child components using the notification data, this way all
//the components using the notification data will get the updated data
setNotificationData(data);
if (data.type && data.type === "notification") {
setStatus(true);
setTotalNotification(data.notifications_unread);
}
};
});
...
Your index.js
file
...
// Wrap your app with Notification Provider
<NotificationDataProvider>
<App />
</NotificationDataProvider>
...
Somewhere in the cdild components where you want to use the notification data
const SomeOtherComponentWhereDataIsUsed = () => {
//use the notification data in this component but beware untill it
//is set in that useEffect of the above component it will be an undefined value
const { notificationData } = useNotificationDataContext()
//use this notificationData
...
}
References: