0

New to React Hooks and unsure how to solve. I have the following snippet of code within my App.js file below.

What I am basically trying to achieve is to get the user logged in by calling the getUser() function and once I have the user id, then check if they are an authorised user by calling the function checkUserAccess() for user id.

Based on results within the the validIds array, I check to see if it's true or false and set authorised state to true or false via the setAuthorised() call.

My problem is, I need this to process first prior to performing my first render within my App.js file.

At the moment, it's saying that I'm not authroised even though I am.

Can anyone pls assist with what I am doing wrong as I need to ensure that authorised useState is set correctly prior to first component render of application, i.e. path="/"

const [theId, setTheId] = useState('');
const [authorised, setAuthorised] = useState(false);


  const checkUserAccess = async (empid) => {
    try {
      const response = await fetch("http://localhost:4200/get-valid-users");
      const allUsers = await response.json();

      const validIds = allUsers.map(({ id }) => id);
      const isAuthorised = validIds.includes(empid);

      if (isAuthorised) {
        setAuthorised(true)
      } else {
        setAuthorised(false)
      }
    } catch (err) {
      console.error(err.message);
    }
  }  
    
    const getUser = async () => {
        try {
          const response = await fetch("http://localhost:4200/get-user");
          const theId= await response.json();
          
          setTheId(theId);
          checkUserAccess(theId);
    
        } catch (err) {
          console.error(err.message);
        }
      }
    
     useEffect(() => {
        getUser();
      }, []);  
13
  • 1
    I'd add another useEffect triggered by theId value, and that should call the checkUserAccess function Commented Jun 17, 2021 at 9:10
  • Personally I would use 1 useSstate & 1 useEffect,.. Otherwise you get multiple renders for no reason. Commented Jun 17, 2021 at 9:20
  • @MarioVernari - could you please provide an example of your solution by possibly using my snippet of code. Commented Jun 17, 2021 at 9:32
  • 1
    If you look at the example I posted, I do -> if (!user) return <div>Loading</div>; This should stop the redirect, as it will wait until the setUser is called before deciding to redirect or not. Commented Jun 17, 2021 at 9:48
  • 1
    Yeah, basically me and @Keith done the same thing) Commented Jun 17, 2021 at 9:50

2 Answers 2

1

Unless you are wanting to partially render when you get the user ID, and then get the access level. There is no reason to have multiple useState's / useEffect's.

Just get your user and then get your access level and use that.

Below is an example.

const [user, setUser] = useState(null);

const checkUserAccess = async (empid) => {
  const response = await fetch("http://localhost:4200/get-valid-users");
  const allUsers = await response.json();
  const validIds = allUsers.map(({ id }) => id);
  const isAuthorised = validIds.includes(empid);
  return isAuthorised;
}  
    
const getUser = async () => {
  try {
    const response = await fetch("http://localhost:4200/get-user");
    const theId= await response.json();
    const access = await checkUserAccess(theId);
    setUser({
      theId,
      access
    });
  } catch (err) {
    console.error(err.message);
  }
}
    
useEffect(() => {
  getUser();
}, []);  

if (!user) return <div>Loading</div>;

return <>{user.theId}</>
Sign up to request clarification or add additional context in comments.

Comments

1

This way it should work but keep in mind that you must render your app only if theId in the state is present, which will mean your user is properly fetched.

const [state, setState] = useState({ theId: '', isAutorized: false })    
const getUser = async () => {
  try {
    const idResp = await fetch("http://localhost:4200/get-user");
    const theId = await idResp.json();
    const authResp = await fetch("http://localhost:4200/get-valid-users");
    const allUsers = await authResp.response.json();

    const validIds = allUsers.map(({ id }) => id);
    const isAuthorised = validIds.includes(theId);
    setState({ theId, isAuthorised })
  } catch (err) {
    console.error(err.message);
  }
}

useEffect(() => {
   getUser();
}, []);

if (!state.theId) return <div>Loading</div>;

if (state.theId && !isAuthorized) return <AccessNotAllowed />

return <Home />

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.