React is calling function unexpectedly - javascript

Here is my Login component:
const Login = () => {
const [user, setUser] = useState("");
const [pass, setPass] = useState("");
return (
<div>
<p>Login</p>
<input
type="text"
onChange={(e) => {
setUser(e.target.value);
}}
/>
<input
type="password"
onChange={(e) => {
setPass(e.target.value);
}}
/>
<button onClick={submit(user, pass)}>
Submit
</button>
</div>
);
};
It renders on my webpage, but it calls the submit() function whenever I input to these two: text and password. Looking at my code, I've only set the onClick to call the submit function.
Is there something wrong with my code?
EDIT: Removed classNames for easier viewing

You are calling the submit function on every render. onClick takes a function, but you are directly calling a function.
<button onClick={submit(user, pass)}>
Submit
</button>
will be replaced by
<button onClick={()=>submit(user, pass)}>
Submit
</button>

try :
const Login = () => {
const [user, setUser] = useState("");
const [pass, setPass] = useState("");
const onSubmit = () => {
submit(user,pass)
}
return (
<div>
<p>Login</p>
<input
type="text"
onChange={(e) => {
setUser(e.target.value);
}}
/>
<input
type="password"
onChange={(e) => {
setPass(e.target.value);
}}
/>
<button onClick={onSubmit}>
Submit
</button>
</div>
);
};

Related

Why the function is invoked for every input in React component?

I try to learn react component rendering but the problem is that I have a login page with 2 input field and 1 button as:
function LoginPage() {
const [username, changeUsername] = useState('');
const [password, changePassword] = useState('');
const loginRequest = async (username, password) => {
let response = await service.loginRequest(username, password);
console.log(response);
}
return (
<Card hoverable className='transaction-button-card'>
<h1>Enter username and password</h1>
<input type="text"
placeholder="Username"
onChange={e => changeUsername(e.target.value)}
value={username}></input>
<input type="text"
placeholder="Password"
onChange={e => changePassword(e.target.value)}
value={password}></input>
<Button onClick={loginRequest(username, password)}
className='withdraw-deposit-button'>Login/Deposit</Button>
</Card>
);
}
export default LoginPage;
When the page is rendered the function loginRequest(username, password) automatically triggered once and for every input characters to input fields are also triggering the same function and sending request for each input char. How can I solve this problem? (I don't want to send request automatically when the page is opened and send request with only with button). I would appreciate if you define the problem.
`
function LoginPage() {
const [username, changeUsername] = useState('');
const [password, changePassword] = useState('');
const loginRequest = async (username, password) => {
let response = await service.loginRequest(username, password);
console.log(response);
}
return (
<Card hoverable className='transaction-button-card'>
<h1>Enter username and password</h1>
<input type="text"
placeholder="Username"
onChange={e => changeUsername(e.target.value)}
value={username}></input>
<input type="text"
placeholder="Password"
onChange={e => changePassword(e.target.value)}
value={password}></input>
<Button onClick={() => loginRequest(username, password)}
className='withdraw-deposit-button'>Login/Deposit</Button>
</Card>
);
}
export default LoginPage;
`

React review form not submitting review on submit

I just want to preface this that I am learning JavaScript and React so this is all very new to me.
I am building a "simple" movie rating app and need to be able to push a review to a div "on submit" and cannot figure out how to do so. I have tried using update state in react and/or creating functions to try to accomplish this and cannot figure out how to do this for the life of me. I did somewhat succeed using the latter method, but was getting errors about using unique key props. The other problem was I am to use a star-rating component and when I submitted the review, it wasn't pushing that to the div. This is where I'm at currently:
import { Button, Form, Input } from "reactstrap";
import Stars from "./stars";
export default function ReviewForm() {
const [reviews, setReviews] = useState("");
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
console.log("Form Submitted");
};
return (
<div className="form-container">
<Stars />
<Form onSubmit={onSubmit}>
<Input
className="form-control" type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
</Form>
</div>
);
}
// This is what I have in my Stars component:
import React, { useState } from "react";
import { FaStar} from 'react-icons/fa'
const Stars = () => {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(null);
return(
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return <label>
<input
type="radio"
name="rating"
value={ratingValue}
onClick={() => setRating(ratingValue)}
/>
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "gold" : "lightgray"}
size={20}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>;
})}
<p>I rate this movie {rating + " stars"}</p>
</div>
);
};
export default Stars```
Here is the working version of your code. You should use key in your map and e.preventDefault() in your form submit function. As final touch you should set another state inside your form submit and show this value in a div or some html element. Also I see that you want to get child state into parent so you can call callback for this https://codesandbox.io/embed/brave-euler-ybp9cx?fontsize=14&hidenavigation=1&theme=dark
ReviewForm.js
export default function ReviewForm() {
const [reviews, setReviews] = useState("");
const [value, setValue] = useState("");
const [star, setStar] = useState();
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
e.preventDefault();
setValue(reviews + " with " + star + " star ");
};
return (
<div className="form-container">
<Stars setStar={setStar} />
<Form onSubmit={onSubmit}>
<Input
className="form-control"
type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
<div>{value}</div>
</Form>
</div>
);
}
Stars.js
const Stars = ({ setStar }) => {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(null);
const handleClick = (ratingValue) => {
setRating(ratingValue);
setStar(ratingValue);
};
return (
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<label key={i}>
<input
type="radio"
name="rating"
value={ratingValue}
onClick={() => handleClick(ratingValue)}
/>
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "gold" : "lightgray"}
size={20}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>
);
})}
<p>I rate this movie {rating + " stars"}</p>
</div>
);
};
export default Stars;
You probably are seeing a page refresh when you press the submit button. This is the default behavior of HTML forms.
When using React or any front-end framework, you'd want to handle the form submission yourself rather than letting the browser submit your forms.
In your onSubmit function, add the following line
e.preventDefult()
const onSubmit = (e: any) => {
e.preventDefault()
console.log("Form Submitted");
};
Your code will work perfectly.
import { Button, Form, Input } from "reactstrap";
import Stars from "./stars";
export default function ReviewForm() {
const [Reviews, setReviews] = useState("");
const [ReviewsRating, setReviewsRating] = useState(5);
const [Reviews_, setReviews_] = useState([]);
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
e.preventDefault()
console.log("Form Submitted");
//After upload to the server
setReviews_([Reviews, ...Reviews_]
};
return (
<div className="form-container">
<Stars getRating={getRating}/>
<Form onSubmit={onSubmit}>
<Input
className="form-control" type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
</Form>
<div class="reviews">
{Reviews_.map(item => <div> {item}</div> )}
</>
</div>
);
}```
Then to get the stars rating value use props like...
And make sure you call that property (function) inside your Starts component
const getRating =(value)=>{
setReviewsRating(value)
}

BootStrap Modal is refreshed on KeyPress

I know there are question asked before, but I have tried the solution but it's not working. I have split the component differently but then also it refresh on every single keypress.
const TenementRegistration = () => {
const [show, setShow] = useState(false);
const [name, setName] = useState("");
const [editId, setEditId] = useState("");
function Example() {
const onSubmitHandler = async () => {
const data = {
name: name
}
await services.postService("User", data).then((res) => {
onGetUserData();
});
}
return(
<Modal
show={show}
onHide={() => setShow(false)}
size="lg"
aria-labelledby="example-custom-modal-styling-title"
scrollable="true"
centered
animation="true"
>
<Modal.Header closeButton>
<Modal.Title id="example-custom-modal-styling-title">
Add User
</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="form-container">
<form>
<Row>
<div className="form-group col-12 col-md-6
center">
<label for="inputName" className="asy-
FormLabel">
Name
</label>
<input
type="text"
className="form-control asy-InputValues"
id="policyName"
placeholder="Enter Property Id"
onChange={(e) => {
setName(e.target.value);
}}
value={name}
required
/>
</div>
</Row>
</form>
</div>
</Modal.Body>
<Modal.Footer>
<button
type="button"
className="submit-button"
onClick={() => {
onSubmitHandler();
}}
>
Submit
</button>
</Modal.Footer>
</Modal>
const [data, setData] = useState([]);
useEffect(() => {
onGetUserData();
}, []);
const onGetUserData = async () => {
services.getService("User").then((res) => {
setData(res.data);
});
};
const onEditData = async (id) => {
setShow(true);
const newData = data.filter((obj) => obj.id === id)[0];
setName(newData.name);
}
//Table where we show name and pass id to update button
}
I have also tried to Split the Modal and separate the form (not in this example) but it didn't work any suggestions how to handle the modal problem
Try this
In your button onClick
<button
type="button"
className="submit-button"
onClick={(event) =>
{
onSubmitHandler(event);
}}
>
Submit
</button>
then in that function:
const onSubmitHandler = async (event) => {
event.preventDefault()
const data = {
name: name
}
await services.postService("User", data).then((res) => {
onGetUserData();
});
}

how to check if the fetch variable has data

function Login() {
const [email, setEmail] = useState("");
const [password, setpassword] = useState("");
const [users, setUser] = useState([]);
function login() {
fetch(
"http://116.202.231.219:8069/Restaurant/Login_Updated?Cont4=" +
email +
"&Pswd=" +
password
).then((result) => {
result.json().then((resp) => {
// console.warn(resp)
setUser(resp);
console.log(resp);
});
});
}
return (
<div className="col-sm-6 offset-sm-3">
<h1>Login Page</h1>
<br />
<input
type="text"
className="form-control"
onChange={(e) => setEmail(e.target.value)}
/>
<br />
<br />
<input
type="password"
className="form-control"
onChange={(e) => setpassword(e.target.value)}
/>
<br />
<br />
<button onClick={login} className="btn btn-primary">
Login
</button>
</div>
);
}
now I want to check that if the data being fetched is the same as the data being put in the inputs so I am trying using "IF" but the "RESP" variable is not global I mean that it is not working with "IF". So can you guys help me how to do a check that the Email pass is equal to the Email pass from the API.
As you can see that API is getting the cont4 and pass from the input tags and giving back the objects in return but I am not able to run the success check on this API that if it returns object go to dashboard else throw alert of error
import axios from 'axios';
//add axios in your project
function Login() {
const [email, setEmail] = useState("");
const [password, setpassword] = useState("");
const [users, setUser] = useState({});
loginHandel = () => {
const url = `http://116.202.231.219:8069/Restaurant/Login_Updated?Cont4=${email}&Pswd=${password}`
axios.get(url).then((res) => {
//check the res if its getting the correct data or not?
//restructure accordingly
console.log(res);
const persons = res;
if ((persons?.email === email) && (persons?.password === password)) {
//perform any thing here
setUser(persons);
} else {
console.log("User email and passwoed mismatched!")
}
}).catch(err => {
//handel your error
console.log(err);
})
}
return (
<div className="col-sm-6 offset-sm-3">
<h1>Login Page</h1>
<br />
<form>
</form>
<input
type="text"
className="form-control"
onChange={(e) => setEmail(e.target.value)}
/>
<br />
<br />
<input
type="password"
className="form-control"
onChange={(e) => setpassword(e.target.value)}
/>
<br />
<br />
<button onClick={loginHandel} className="btn btn-primary">
Login
</button>
</div>
);
}

React submit form returns event.preventDefault is not a function

I'm having a problem with a simple form registration submit. Here's the code:
import React from 'react';
import {register} from 'Util/api'
function Registration() {
const [email, setEmail] = React.useState("")
const [password, setPassword] = React.useState("")
const [passwordCheck, setPasswordCheck] = React.useState("")
const [error, setError] = React.useState("")
const register = event => {
event.stopPropagation()
event.preventDefault()
register(email, password, passwordCheck).then(res => {
console.log(res)
}).catch(error => {
console.log(error)
})
}
return (
<div>
<form onSubmit={register}>
<div>
<label>Email:
<input
type="text"
placeholder="Email"
value={email}
onChange={ev => setEmail(ev.target.value)}
/>
</label>
</div>
<div>
<label>Password:
<input
type="password"
placeholder="Password"
value={password}
onChange={ev => setPassword(ev.target.value)}
/>
</label>
</div>
<div>
<label>Repeat password:
<input
type="password"
placeholder="Repeat password"
value={passwordCheck}
onChange={ev => setPasswordCheck(ev.target.value)}
/>
</label>
</div>
<button type="submit" value="Submit">Register</button>
{error && (
<div>{error}</div>
)}
</form>
</div>
);
}
export default Registration
When I click the button "register" the console returns the error:
Registration.js:12 Uncaught TypeError: event.stopPropagation is not a function
Same thing happen with event.preventDefault if I delete that line. It looks very similar to the example in the doc here...
What's wrong with my code?
You have a name collision - there are 2 identifiers named register:
import {register} from 'Util/api'
and
const register = event => {
event.stopPropagation()
event.preventDefault()
register(email, password, passwordCheck).then(res => {
In the second code, you want to refer to the imported function, not the handler, but since the handler is lexically closer, register refers to the handler there - it calls itself recursively, with a first parameter of email, which is not actually an event, so stopPropagation and preventDefault can't be called on it.
Use a different name:
const handleSubmit = event => {
event.stopPropagation()
event.preventDefault()
register(email, password, passwordCheck).then(res => {
console.log(res)
}).catch(error => {
console.log(error)
})
}
<form onSubmit={handleSubmit}>
You have two register. Please change
const register = event =>
to
const submitHandler = event =>
and
<form onSubmit={register}>
to
<form onSubmit={submitHandler}>

Categories