skip to Main Content

I want to connect react-router-dom with my login page. But it doesn’t work how I want. Attribute "to" of Link element refresh after I click button. I want to change this attribute after button clicked.

Everything works fine. When I type correct email and password, conditions work, console log correct messages. When I click again button, Link works well and moves me to /home (there is my home page).

  const loggedUser = Users.filter(({ email }) => email === emailInput);
  const [linkTo, setLinkTo] = useState('/');
  const [showLink, setShowLink] = useState(false);

  const handleLoginButton = () => {
    const password = loggedUser.map(({ password }) => password)[0];
    console.log(password);

    if (!loggedUser) {
      console.log('Error in your email');
    } else {
      console.log('Correct email');

      if (passwordInput === password) {
        console.log('and correct password!');
        setLinkTo('/home');
        setShowLink(true);

        console.log(linkTo);
      } else {
        console.log('but wroing password');
        setLinkTo('/');
        setShowLink(false);
        console.log(linkTo);
      }
    }
  };

Button:

<Link to={linkTo}>
  <LoginButton onClick={handleLoginButton}>Login</LoginButton>
</Link>

What is another solution to this problem?

2

Answers


  1. It seems the issue here might be related to the use of the Link component from react-router-dom inside the click handler of the login button. The Link component works by changing the URL immediately upon rendering, so setting its to attribute dynamically after a button click might not work as expected.

    Instead of using the Link component directly inside the click handler, consider using the history object from react-router-dom to programmatically navigate after a successful login.

    Here’s an example of how you can achieve this:

    import { useHistory } from 'react-router-dom';
    
    // Inside your functional component
    const history = useHistory();
    
    const handleLoginButton = () => {
      const loggedUser = Users.find(({ email }) => email === emailInput);
    
      if (!loggedUser) {
        console.log('Error in your email');
      } else {
        console.log('Correct email');
    
        const { password } = loggedUser;
        if (passwordInput === password) {
          console.log('and correct password!');
          history.push('/home'); // Programmatically navigate to '/home' on successful login
        } else {
          console.log('but wrong password');
        }
      }
    };
    
    // Button without Link component
    <LoginButton onClick={handleLoginButton}>Login</LoginButton>
    

    By using useHistory hook provided by react-router-dom, you can access the history object and call its push method to navigate to the desired route after a successful login without relying on the Link component directly within the click handler.

    Login or Signup to reply.
  2. My suggestion is trying to understand where to use HTML Tags first. By which case, HTML hyerlink and button, as we all know they have their own attributes and different event handler methods.
    You should have to use polymorphic component if you were to use button as a link or link as button. And Nothing is make-sense to use link in form submit.

    But I’ll share you a recommended note that might be a good help to you.

    import { useNavigate } from 'react-router-dom';
    
    const LoginForm = () => {
      const navigate = useNavigate();
    
      const handleSubmit = () => {
          navigate('route'); // Add your route name
      }
    
      return (
         <form>
           <Input label="Username" placeholder="Username" />
           <Input label="Passowrd" placeholder="Password" type="password" />
           <Button onClick={handleSubmit}>Submit</Button>
         </form>
       );
    }
    
    

    My recommended way

    const LoginForm = () => {
      const navigate = useNavigate();
    
      const handleSubmit = (data) => {
          console.log(data);
          navigate(route); // Add your route name
      }
    
      return (
         <form onSubmit={handleSubmit}>
           ...
           <Button type="submit">Submit</Button> 
         </form>
       );
    }
    
    // Note : type Props is optional. The button inside form is automatically type submit.
    

    Additional Suggestions

    Handling form in React.js, manually, is a little complex in which validation, re-rendering and something more.

    It’s better to use third-party library like react-hook-form, formik and mantine-form.

    Validtion with Zod is a bonus point.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search