React中如何监听外部变量变化

Mar*_*all 4 javascript variables reactjs axios

希望你做得很好 :)

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

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();
Run Code Online (Sandbox Code Playgroud)

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

useEffect(() => {
    getActiveGames();
    if (token && userId) {
      getCart();
      getWallet();
      getWalletPayments();
    }
  }, []);
Run Code Online (Sandbox Code Playgroud)

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

如果你能帮忙那就太好了:)

lis*_*tdm 6

选项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]);
Run Code Online (Sandbox Code Playgroud)

选项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>
}
Run Code Online (Sandbox Code Playgroud)

在你的 App.js 中

return (<UserProvider>
    ...
</UserProvider)
Run Code Online (Sandbox Code Playgroud)

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

 const userId = useContext(UserContext);

 useEffect(() => {
    getActiveGames();
    if (token && userId) {
       getCart();
       getWallet();
       getWalletPayments();
    }
 }, [userId]);
Run Code Online (Sandbox Code Playgroud)