更新 axios post 请求中的全局状态

发布于 2025-01-10 22:07:31 字数 1657 浏览 0 评论 0原文

我有一个全局令牌变量,每当我使用 axios 发出 API 请求时,我都想更新该变量。我遇到的问题是如何更新 token 变量,因为 axios 请求不是在功能组件中发出的,所以在发出此类请求时我无法利用 React hooks。

const logInUser = async (usernameOrEmail, password) => {

  //const myContext = useContext(AppContext);
  //^ gives an error b/c it's a react hook

  axios
      .post(
        `https://jellybackend.herokuapp.com/authenticate`, {
          username: usernameOrEmail,
          password: password,
        })
      .then((response) => {
    
        //myContext.setToken(response.data.token); //update token set , error since not a functional component
        console.log(response);
      
        tokenGlobal = response.data.token


      })
      .catch((error) =>
      console.log(error)
      );
};

我正在将我的令牌设置为全局状态,因此我在 App.js 中定义了钩子,如下所示

export default function App() {
  
  //define global variable of token
  const [token, setToken] = useState("");

  const userSettings = {
    token: "",
    setToken,
  };


  return (
    <AppContext.Provider value={userSettings}>
     ...
      
    </AppContext.Provider>
  );
}

任何有关如何更新我的全局状态变量或如何重构我的代码的想法将非常感激!

我最终希望发生的是,每当用户登录时,令牌都会更新,因为这是从 axios post 请求返回的内容。

下面的按钮是用户登录的方式

function LoginScreen(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  
  const myContext = useContext(AppContext);


  return (
    ...
        <Button
          onPress={ () =>  {logInUser(email, password);} //I want to update the token here...
          w="40%"
          py="4"
          style={styles.button}
        >

I have a global token variable that I want to update whenever I make an API request with axios. The problem that I am having is how to update the the token variable since the axios request is not made in a functional component, so I am not able to take advantage of React hooks when making such request.

const logInUser = async (usernameOrEmail, password) => {

  //const myContext = useContext(AppContext);
  //^ gives an error b/c it's a react hook

  axios
      .post(
        `https://jellybackend.herokuapp.com/authenticate`, {
          username: usernameOrEmail,
          password: password,
        })
      .then((response) => {
    
        //myContext.setToken(response.data.token); //update token set , error since not a functional component
        console.log(response);
      
        tokenGlobal = response.data.token


      })
      .catch((error) =>
      console.log(error)
      );
};

I am making my token a global state, so I have the hook defined in App.js, as seen below

export default function App() {
  
  //define global variable of token
  const [token, setToken] = useState("");

  const userSettings = {
    token: "",
    setToken,
  };


  return (
    <AppContext.Provider value={userSettings}>
     ...
      
    </AppContext.Provider>
  );
}

Any idea on how to update my global state variable, or how to refactor my code would be very appreciated!

What I want eventually to happen is that whenever a user logs in, the token is updated, since that is what is returned from the axios post request.

The button below is how a user logs in

function LoginScreen(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  
  const myContext = useContext(AppContext);


  return (
    ...
        <Button
          onPress={ () =>  {logInUser(email, password);} //I want to update the token here...
          w="40%"
          py="4"
          style={styles.button}
        >

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

请别遗忘我 2025-01-17 22:07:31

一个非常简单且琐碎的重构是将回调函数传递给 logInUser 实用程序。

例子:

const logInUser = async (usernameOrEmail, password, onSuccess, onFailure) => {
  axios
    .post(
      `https://jellybackend.herokuapp.com/authenticate`, {
        username: usernameOrEmail,
        password: password,
      })
    .then((response) => {
      onSuccess(response);
      console.log(response);
    })
    .catch((error) =>
      onFailure(error);
      console.log(error);
    );
};

...

function LoginScreen(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  
  const myContext = useContext(AppContext);

  const successHandler = response => myContext.setToken(response.data.token);

  const failureHandler = error => myContext.setToken(null);

  return (
    ...
    <Button
      onPress={() => logInUser(email, password, successHandler, failureHandler)}
      w="40%"
      py="4"
      style={styles.button}
    >
      ...
    </Button>
    ...
  );
}

A very simple and trivial refactor would be to pass callback functions to the logInUser utility.

Example:

const logInUser = async (usernameOrEmail, password, onSuccess, onFailure) => {
  axios
    .post(
      `https://jellybackend.herokuapp.com/authenticate`, {
        username: usernameOrEmail,
        password: password,
      })
    .then((response) => {
      onSuccess(response);
      console.log(response);
    })
    .catch((error) =>
      onFailure(error);
      console.log(error);
    );
};

...

function LoginScreen(props) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  
  const myContext = useContext(AppContext);

  const successHandler = response => myContext.setToken(response.data.token);

  const failureHandler = error => myContext.setToken(null);

  return (
    ...
    <Button
      onPress={() => logInUser(email, password, successHandler, failureHandler)}
      w="40%"
      py="4"
      style={styles.button}
    >
      ...
    </Button>
    ...
  );
}
微暖i 2025-01-17 22:07:31

您可以在模块中设置 axios 调用,然后该模块可以返回您想要存储在全局状态中的值。

您的 axios 调用本身不必存在于功能组件中,但需要在该解决方案的一个组件中导入/调用。

因此,您可以将 axios 调用更改为模块函数内的调用,然后可以导出该函数,例如 globalsapi.js,然后导入到您的功能组件中:

exports.logInUser = async () =>  {
  const globalData = await axios
   .post(
    `https://jellybackend.herokuapp.com/authenticate`, {
      username: usernameOrEmail,
      password: password,
    });
    const token = await globalData.data.token;
    return token;
}

现在,无论您决定在何处调用 setToken 状态更新,您只需导入该函数并设置全局令牌即可:

import { logInUser } from './globalsapi';

logInUser().then(data => {
    myContext.setToken(data);
});

您可以将所需的任何参数传递给 logInUser 函数。

You could setup your axios call in a module that can then return the value that you would like to store in global state.

Your axios call doesn't have to exist within a functional component per se, but it would need to be imported/called within one for this solution.

So, you could change your axios call to be within a module function that could then be exported, say globalsapi.js, then imported to your functional component:

exports.logInUser = async () =>  {
  const globalData = await axios
   .post(
    `https://jellybackend.herokuapp.com/authenticate`, {
      username: usernameOrEmail,
      password: password,
    });
    const token = await globalData.data.token;
    return token;
}

Now, wherever you decide to call the setToken state update, you can just import the function and set the global token:

import { logInUser } from './globalsapi';

logInUser().then(data => {
    myContext.setToken(data);
});

You could pass whatever parameters needed to the logInUser function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文