在 React 套接字连接后使用上下文共享内容

Use context to share content after socket connection in React

我有一个组件的套接字连接,但它的数据被其他各种组件使用。为了降低复杂性,我尝试使用 contextAPI 在所有其他组件之间共享内容。

这是我的套接字连接代码:

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)
          }
        };
        
    })

但是这样我无法导出我的上下文。我检查了一些具有以下语法的示例:

export const UserContext = React.createContext(userContextTemplate)

但是这个例子只适用于静态数据。

如何才能使此上下文数据在另一个组件中可用?

创建context.js 文件

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
  }
}


将设置数据的套接字文件

...
//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);
    }
  };
});
...

您的 index.js 文件

...
// Wrap your app with Notification Provider
<NotificationDataProvider>
  <App />
</NotificationDataProvider>
...

cdild 组件中您想使用通知数据的地方

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
  ...
}

参考文献:

https://dmitripavlutin.com/react-context-and-usecontext/

https://reactjs.org/docs/context.html