I am trying to set up a React component that includes two text input boxes and a button. When I click on the button, I would like for it to make a post request to the backend. However, either the text boxes activate the function, or the function refuses to activate.
Originally, typing in the boxes would activate the onClick event, and I could get onLogin({username, password}) to fire. In an attempt to get this to stop happening when I typed in the boxes and instead to happen when I clicked the button, I tried to make a click handler function, buttonClickHandler, in my Login() function. Now, clicking on the button doesn’t activate the buttonClickHandler function nor the onLogin() function. While I am new to React and JavaScript and I understand that I may be using the wrong forms of functions (still heavily confused), I was wondering if there’s a deeper structural issue with the way I have my functions set up. Thanks!
import React from 'react';
import './Login.css';
import Button from './button';
import {useState} from 'react';
import axios from 'axios';
import { render } from '@testing-library/react';
function TestToken({token}) {
axios.get('http://localhost:8000/login/test_token', {
headers: {
Authorization: 'Token ' + token
}
}).then(response => {
console.log(response.data);
return(true);
}).catch(error => {
console.log(error + ", token authentication failed!");
return(false);
});
};
function OnLogin({username, password}) {
alert("BUTTON CLICKED RAHHHH");
const [token, setToken] = useState("");
axios.post('http://localhost:8000/login',
{
username: {username},
password: {password}
}
).then(response => {
setToken(response.data.token)
console.log(response.data.user)
}).catch(error => {console.log(error)});
if(TestToken(token)) {
console.log("Logged in!");
} else {
console.log("Log in failed!");
};
return(console.log("OnLogin function concluded!"));
};
export function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
function getUser(event) {
setUsername(event.target.value);
}
function getPassword(event) {
setPassword(event.target.value);
}
const buttonClickHandler = () => {
console.log("Handle activated");
OnLogin({username, password});
}
return(
<div className= "functional-box">
<div className= "login-page">
<div className= "login-title">Log In</div>
<div className= "inputs">
<input className= "input-text" onChange={getUser} type="text" placeholder='Username'/>
<input className= "input-text" onChange={getPassword} type="password" placeholder="Password"/>
</div>
<div className="button-div"><Button className="login-button" text="Login" onClick={buttonClickHandler}></Button></div>
</div>
</div>
);
}
export default Login;
The Login() function is called in my App class and seems to be working fine there because the HTML is showing up.
import './App.css';
import Card from './components/Card.jsx'
import Login from './components/Login.jsx'
import { LoggedInSidebar, LoggedOutSidebar } from './components/Sidebar.jsx';
import React, { useState } from 'react';
import axios from 'axios';
import Button from './components/button.jsx';
class App extends React.Component {
render() {
return (
<div className="main-page">
<div className="topbar">
<div className="topbar-title">Glass Table</div>
</div>
<div className= "main-box-div">
<div className="login-sidebar">
<LoggedOutSidebar></LoggedOutSidebar>
</div>
<div className="functional-box">
<Login></Login>
</div>
</div>
</div>
)
}
}
export default App;
And finally the button class which was borrowed from a template website. I don’t believe that it adjusts the onClick function?
import React from "react";
import styled from "styled-components";
const Button = ({text}) => {
return (
<StyledWrapper>
<button className="animated-button">
<svg
viewBox="0 0 24 24"
className="arr-2"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z" />
</svg>
<span className="text">{text}</span>
<span className="circle" />
<svg
viewBox="0 0 24 24"
className="arr-1"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z" />
</svg>
</button>
</StyledWrapper>
);
};
const StyledWrapper = styled.div`
.animated-button {
position: relative;
display: flex;
align-items: center;
gap: 4px;
padding: 16px 36px;
border: 4px solid;
border-color: transparent;
font-size: 16px;
background-color: inherit;
border-radius: 100px;
font-weight: 600;
color: greenyellow;
box-shadow: 0 0 0 2px greenyellow;
cursor: pointer;
overflow: hidden;
transition: all 0.6s cubic-bezier(0.23, 1, 0.32, 1);
}
.animated-button svg {
position: absolute;
width: 24px;
fill: greenyellow;
z-index: 9;
transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.animated-button .arr-1 {
right: 16px;
}
.animated-button .arr-2 {
left: -25%;
}
.animated-button .circle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
background-color: greenyellow;
border-radius: 50%;
opacity: 0;
transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.animated-button .text {
position: relative;
z-index: 1;
transform: translateX(-12px);
transition: all 0.8s cubic-bezier(0.23, 1, 0.32, 1);
}
.animated-button:hover {
box-shadow: 0 0 0 12px transparent;
color: #212121;
border-radius: 12px;
}
.animated-button:hover .arr-1 {
right: -25%;
}
.animated-button:hover .arr-2 {
left: 16px;
}
.animated-button:hover .text {
transform: translateX(12px);
}
.animated-button:hover svg {
fill: #212121;
}
.animated-button:active {
scale: 0.95;
box-shadow: 0 0 0 4px greenyellow;
}
.animated-button:hover .circle {
width: 220px;
height: 220px;
opacity: 1;
}
`;
export default Button;