score:7

Accepted answer

when you call logout at onclick you are calling hooks from your function logout outside of a component body, what's is not allowed.

you can abstract your logout logic to a custom hook where it returns the logoutuser function:

export default function uselogout() {
    
  const history = usehistory();

  // we don't useeffect here, we are only interested in function logoutuser

  const logoutuser = () => {
      const response = axiosinstance.post('user/logout/blacklist/', {
          refresh_token: localstorage.getitem('refresh_token'),
      });
      localstorage.removeitem('access_token');
      localstorage.removeitem('refresh_token');
      axiosinstance.defaults.headers['authorization'] = null;
      history.push('/login');
    }

  return { logoutuser }
};

then you consume your custom hook at your loginuser component body, extracting the logoutuser method:

function loginuser()
{
    const user = useselector(selectuser);
    // use hook at component body extracting logoutuser method
    const { logoutuser } = uselogout();

    const dispatch = usedispatch();

    const handlelogout = (e) =>
    {
        if(e) e.preventdefault();

        dispatch(logout());
    };

    const userloggedinalert = () =>
    {
        return <container>
            <span>
                you are already logged in!
            </span>
            <button
                component={navlink}
                variant="contained"
                color="primary"
                to="/logout"
                // here now you can safely logout user since no hooks are being called
                onclick={function(){  handlelogout(); logoutuser()}}
            >
                do you want to logout?
            </button>

              </container>
        };

    return (
        <container>
            {user ? <userloggedinalert/> : <signin/> }
        </container>
    );
}
export default loginuser;

you can take a step ahead and simplify your logout component:

export default function logout() {
    
  const { logoutuser } = uselogout();

  useeffect(() => {
    logoutuser()
  });
  return <div>logout</div>;
};

edit

for simplicity at your logout.js do as:

export const uselogout = () => {
    
  const history = usehistory();

  // we don't useeffect here, we are only interested in function logoutuser

  const logoutuser = () => {
      const response = axiosinstance.post('user/logout/blacklist/', {
          refresh_token: localstorage.getitem('refresh_token'),
      });
      localstorage.removeitem('access_token');
      localstorage.removeitem('refresh_token');
      axiosinstance.defaults.headers['authorization'] = null;
      history.push('/login');
    }

  return { logoutuser }
};

export default function logout() {

  const { logoutuser } = uselogout();

  useeffect(() => {
    logoutuser()
  });
  return <div>logout</div>;
};

at your your login you import the hook with curly brackets:

import { uselogout } from '../auth/logout';

and at your index.js without the curly brackets you import the component:

import logout from './components/auth/logout';


const routing = (
    <router>
                <route path="/logout" component={logout} />
    </router>
);

score:1

components are basically function references, and you are invoking them, so instead of doing signin(), try <signin />

edit: and make userloggedinalert start with upper case, then all together:

{user ? <userloggedinalert /> : <signin />}


Related Query

More Query from same tag