首页 > 解决方案 > 如何在 React 中监听外部变量的变化

问题描述

希望你做得很好 :)

我有一个“auth.js”文件,带有 aysnc 函数来获取用户 ID 然后将其存储在会话存储中。这里是:

export let userId = sessionStorage.getItem("userId");

const getUserId = async () => {
  if (token) {
    await axios
      .get(`${baseURL}/auth/user`, {
        headers: {
          authorization: token
        }
      })
      .then(function (response) {
        const { data } = response;
        return sessionStorage.setItem("userId", data.userId);
      })
      .catch(function (err) {
        return undefined;
      });
  }
};
getUserId();

然后我在所有需要它的组件中访问这个变量,以便发出其他请求。App.js 中的示例:

useEffect(() => {
    getActiveGames();
    if (token && userId) {
      getCart();
      getWallet();
      getWalletPayments();
    }
  }, []);

问题是,在第一次渲染中,userId 为空(显然),我正在尝试不同的方法来更新甚至重新渲染,以获取更新的值,但似乎没有任何效果。我知道有一个基本的解决方案,但我就是想不通。

如果您能提供帮助,那就太棒了:)

标签: javascriptreactjsvariablesaxios

解决方案


选项1 :

如果想知道sessionStorage中userId是什么时候填写的:
  1. 添加userId您的组件状态。
  2. 监听storage事件。请参阅存储事件
  3. 将 userId 添加为依赖项useEffect
const getUserId = ()=> sessionStorage.getItem("userId");
const [userId, setUserId] = useState(getUserId());
    
useEffect(() => {
  const storage = (event) => {
    if(event.originalEvent.storageArea===sessionStorage){
       const data = getUserId();
       if(data) setUserId(data);
    } 
  };
  window.addEventListener("storage", storage);
   
  return ()=> window.removeEventListener("storage", storage)
}, []);
    
useEffect(() => {
  getActiveGames();
  if (token && userId) {
     getCart();
     getWallet();
     getWalletPayments();
  }
}, [userId]);

选项 2:

您可以管理userId使用上下文

  1. 作为getUserId回报data.userId
const UserContext = React.createContext();

const UserProvider = ({children}) => {
  const [userId, setUserId] = useState(null);

  useEffect(()=> {
    getUserId()
     .then(user => setUserId(user));
  }, []);

  return <UserContext.Provider value={userId}>
          {children}
         </UserContext.Provider>
}

在你 App.js

return (<UserProvider>
    ...
</UserProvider)

使用应用程序中任何组件的 userId:

 const userId = useContext(UserContext);

 useEffect(() => {
    getActiveGames();
    if (token && userId) {
       getCart();
       getWallet();
       getWalletPayments();
    }
 }, [userId]);

推荐阅读