Home > Blockchain >  Update global state in axios post request
Update global state in axios post request

Time:03-02

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

CodePudding user response:

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

CodePudding user response:

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.

  • Related