how to use onClick on react-ripples? - reactjs

i create component MyButton1 to use react-ripples, but when i use onClick in MyButton1, it's not working
it's working normaly if i use button tag but i want to use my component
my code :
export const Register = () => {
const postRegister = () => {
axios.post('http://localhost:3001/api/user/register', {
email: email,
username: username,
password: password,
})
.then(() => {
alert('đăng kí thành công')
})
.catch(err => alert(err));
}
const register = () => {
console.log('onClick work')
postRegister()
}
return (
<div className="login-site">
<form className='form-login'>
<h1 className='login-form-title'>Đăng Kí</h1>
<div className="form-row">
<input onChange={getEmail} type="email"
name="email" placeholder="Your Email" />
</div>
<div className="form-row">
<input value={username} onChange={getUsername} type="email"
name="email" autocomplete="off" placeholder="Tên đăng nhập" />
</div>
<div className="form-row">
<input value={password} onChange={getPassword} type="password"/>
</div>
<div className="form-button-right">
Quên mật khẩu?
</div>
<div className="form-button-center">
<div>
<MyButton1 onClick={register}>Đăng kí</MyButton1>
</div>
Đăng nhập
</div>
</form>
</div>
);
}
in MyButton1 component code:
export const MyButton1 = (props) => {
return (
<Ripples color="rgba(255,255,255,0.5)" during={650}>
<Button className='my-button-1'>{props.children}</Button>
</Ripples>
);
}

Your MyButton1 doesn't have an onClick props
Since the onClick handler is only available on the native HTML element, you would need to pass it down to your Button component which supposedly also have that handler already.
Something like this:
export const MyButton1 = (props) => {
return (
<Ripples color="rgba(255,255,255,0.5)" during={650}>
<Button className="my-button-1" onClick={props.onClick}>{props.children}</Button>
</Ripples>
);
};

Related

Clear all fields after submit React js

I have the following code in my react app and I need to have empty input areas after submitting. Please assist me.
import { useRef } from 'react';
import './Contact.css';
import emailjs from 'emailjs-com'
import { useState, useEffect } from 'react';
const Contact = () => {
const formRef = useRef();
const [done, setDone] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
emailjs.sendForm(
'service_py6v3mm',
'template_db5q8nx',
formRef.current,
'mJDC1if10C25Z-TZC'
)
.then((result) => {
console.log(result.text);
setDone(true);
}, (error) => {
console.log(error.text);
});
}
return (
<div className="c">
<div className='c-wrapper'>
<div className='c-left'>
<h1 className='c-title'> Let's discuss!</h1>
<div className='c-info'>
<div className='c-info-item'>
<div className="c-info-item">
<img
src="./images/Phone.jpg"
alt=""
className="c-icon"
/>
+12345678 </div>
<div className="c-info-item">
<img className='c-icon'
src="./images/Email.png" alt='Email' />
messimacky#gmail.com
</div>
<div className="c-info-item">
<img className='c-icon'
src="./images/Location.jpeg"
alt=" " />
Addis Ababa, Wolo Sefer, Ethio-China Road, Ethiopia
</div>
</div>
</div>
</div>
<div className='c-right'>
<p className='c-desc'> <b> Get in touch!</b>
</p>
<form ref={formRef} onSubmit={handleSubmit}>
<input type='text' placeholder='Name' name='username' />
<input type='text' placeholder='Subject' name='user_subject' />
<input type='text' placeholder='Your email here... ' name='user_email' />
<textarea rows={5} placeholder='message' name='message' /> <br />
<button>Submit</button>
{done && <p> Thank you I will contact you soon!</p>}
</form>
</div>
</div>
</div>
)
}
export default Contact
You can bind every input value to a state and empty them when you submit it. Here I add an example for the username. You can multiply it and use it.
const [username, setUsername] = useState('Name');
const submitFunctionWhichDeletes = () => {
console.log(username);
setUsername('');
}
<input ... value={username} onChange={e => setUsername(e.target.value)} ... />
const compForm = ()=>{
const [formData,addFormData] = useState({
username:"",
subject:"",
email:"",
message:""
})
cosnt formSubmit =()=>{
// make api call
addFormData({
username:"",
subject:"",
email:"",
message:""
})
}
const formData = (e,filed)=>{
const temp = {...formData}
if (filed === "username"){
temp.username = e.target.value
}
else if(filed === "subject"){
temp.subject = e.target.value
}
else if(filed === "email"){
temp.email = e.target.value
}
else if(filed === "message"){
temp.message = e.target.value
}
addFormData(temp)
}
return(
<>
<input type='text' placeholder='Name' name='username'
value={formData.username} onChange={(e)=>formData(e,username)}/>
<input type='text' placeholder='Subject' name='user_subject'
value={formData.subject} onChange={(e)=>formData(e,subject)}/>
<input type='text' placeholder='Your email here... ' name='user_email'
value={formData.email} onChange={(e)=>formData(e,email)}/>
<textarea rows={5} placeholder='message' name='message'
value={formData.message} onChange={(e)=>formData(e,message)}/>
<button onClick = {(e)=>formSubmit()}>Submit</button>
<>
)
}

React, functional component. Input focus is thrown off when a character is entered

I'm new in react. The problem is this - when I enter data into the input, my focus is reset. I understand that it happens due to changeHandler. But I don't understand how to change it. I've seen similar problems, but they are all related to class components. I would like to implement the solution exactly in a functional component, not using classes.
import React, { useContext, useEffect, useState } from 'react'
import { AuthContext } from '../context/AuthContext'
import axios from 'axios';
import { render } from '#testing-library/react';
export const AuthPage = () => {
const auth = useContext(AuthContext)
const [typeOfForm, setTypeOfForm] = useState('login')
const [form, setForm] = useState({
email: '', password: ''
})
const loginHandler = async () => {
try {
var config = {
headers: { 'Access-Control-Allow-Origin': '*' }
};
axios.post('http://localhost:5000/api/login', { ...form }, { headers: { 'Authorization': `Bearer ${auth.token}` } })
.then(response => response.data.map(part => { auth.login(part.token, part.userId); console.log(part) }))
.catch(function (error) {
console.log(error);
});
} catch (e) { }
}
const registerHandler = async () => {
try {
var config = {
headers: { 'Authorization': `Bearer ${auth.token}` }
};
axios.post('http://localhost:5000/api/register', { ...form })
.then(response => response.data.map(part => { auth.login(part.token, part.userId); console.log(part) }))
.catch(function (error) {
console.log(error);
});
} catch (e) { }
}
const changeHandler = event => {
setForm({ ...form, [event.target.name]: event.target.value })
}
return (
<div className="App" key="editor2">
<div className="logreg-bg"></div>
<a href="/">
<h1 id="logreg-logo">Animal Assistance <br /> <span id="logreg-logo-down">save nature togehter</span></h1>
</a>
{typeOfForm == 'login' ? <LoginForm /> : <RegisterForm />}
<h1 id="logreg-logo2"> Created by: <br /> <span id="logreg-logo-down2">PTN</span></h1>
</div>
);
function LoginForm() {
return (
<div id="logreg-form-container">
<h1 id="form-header">Log in</h1>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="email" id="login-label">Email</label>
</div>
<input
placeholder="Email"
type="text"
id="login"
name="email"
value={form.email}
onChange={changeHandler}
required />
</div>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="password" id="password-label">Password</label>
</div>
<input
placeholder="Password"
type="password"
id="password"
name="password"
value={form.password}
onChange={changeHandler}
required />
<div id="logreg-button-container">
<button
onClick={registerHandler}
id="logreg-form-button"
>Login</button>
</div>
</div>
<div id="go-to-else-container">
<a id="go-to-else"
onClick={() => setTypeOfForm('register')}>Register</a>
</div>
</div>
)
}
function RegisterForm() {
return (
<div id="logreg-form-container">
<h1 id="form-header">Register</h1>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="email" id="login-label">Email</label>
</div>
<input
placeholder="Введите email"
value={form.email}
onChange={changeHandler}
type="text"
id="login"
name="email"
required />
</div>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="password" id="password-label">Password</label>
</div>
<input
placeholder="Введите пароль"
value={form.password}
onChange={changeHandler}
type="password"
id="password"
name="password"
required />
<div id="logreg-button-container">
<button
type="submit"
id="logreg-form-button"
>Register</button>
</div>
</div>
<div id="go-to-else-container">
<a id="go-to-else"
onClick={() => setTypeOfForm('login')}>Login</a>
</div>
</div>
)
}
}
export default AuthPage;
Problems:
Focus is being lost because currently, input changes the state of a higher level component. The automatically causes a re-rendering of its child (the login or sign up form), because it is being completely defined again.
This causes an automatic re-render since React and browser think it
got a COMPLETELY NEW component.
Solutions:
Move the form state, and changeHandler function, to each respective form component, and allow them to manage their state independently. That way, this won't happen.
Recommended Approach:
If you want to form and changleHandler in a higher level component, then define the child components (Login and Sign Up) separately from AuthPage. Then just pass them the form state, and changeHandler function, as props.
Below if the 2nd approach being implemented
Since you would define both components separately, ensure you pass all the variables and functions in AuthPage, that are needed in each form, as props/parameters too. This is for functional purposes, and because it is best practice for maintenance on react apps.
Let me know if it helps :)
import React, { useContext, useEffect, useState } from 'react'
import { AuthContext } from '../context/AuthContext'
import axios from 'axios';
import { render } from '#testing-library/react';
function LoginForm({form, changeFormType, changeHandler, registerHandler}) {
return (
<div id="logreg-form-container">
<h1 id="form-header">Log in</h1>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="email" id="login-label">Email</label>
</div>
<input
placeholder="Email"
type="text"
id="login"
name="email"
value={form.email}
onChange={changeHandler}
required />
</div>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="password" id="password-label">Password</label>
</div>
<input
placeholder="Password"
type="password"
id="password"
name="password"
value={form.password}
onChange={changeHandler}
required />
<div id="logreg-button-container">
<button
onClick={registerHandler}
id="logreg-form-button"
>Login</button>
</div>
</div>
<div id="go-to-else-container">
<a id="go-to-else"
onClick={changeFormType}>Register</a>
</div>
</div>
)
}
function RegisterForm({form, changeFormType, changeHandler}) {
return (
<div id="logreg-form-container">
<h1 id="form-header">Register</h1>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="email" id="login-label">Email</label>
</div>
<input
placeholder="Введите email"
value={form.email}
onChange={changeHandler}
type="text"
id="login"
name="email"
required />
</div>
<div id="label-logreg-input">
<div className="logreg-labels">
<label htmlFor="password" id="password-label">Password</label>
</div>
<input
placeholder="Введите пароль"
value={form.password}
onChange={changeHandler}
type="password"
id="password"
name="password"
required />
<div id="logreg-button-container">
<button
type="submit"
id="logreg-form-button"
>Register</button>
</div>
</div>
<div id="go-to-else-container">
<a id="go-to-else"
onClick={changeFormType}>Login</a>
</div>
</div>
)
}
const AuthPage = () => {
const auth = useContext(AuthContext)
const [typeOfForm, setTypeOfForm] = useState('login')
const [form, setForm] = useState({
email: '', password: ''
})
const loginHandler = async () => {
try {
var config = {
headers: { 'Access-Control-Allow-Origin': '*' }
};
axios.post('http://localhost:5000/api/login', { ...form }, { headers: { 'Authorization': `Bearer ${auth.token}` } })
.then(response => response.data.map(part => { auth.login(part.token, part.userId); console.log(part) }))
.catch(function (error) {
console.log(error);
});
} catch (e) { }
}
const registerHandler = async () => {
try {
var config = {
headers: { 'Authorization': `Bearer ${auth.token}` }
};
axios.post('http://localhost:5000/api/register', { ...form })
.then(response => response.data.map(part => { auth.login(part.token, part.userId); console.log(part) }))
.catch(function (error) {
console.log(error);
});
} catch (e) { }
}
const changeHandler = event => {
setForm({ ...form, [event.target.name]: event.target.value })
}
const changeFormType = event =>{
//add your condition based of e.target
setTypeOfForm('login')
//add your condition based of e.target
setTypeOfForm('register')
}
return (
<div className="App" key="editor2">
<div className="logreg-bg"></div>
<a href="/">
<h1 id="logreg-logo">Animal Assistance <br /> <span id="logreg-logo-down">save nature togehter</span></h1>
</a>
{typeOfForm == 'login' ? <LoginForm
changeHandler={changeHandler}
form={form}
changeFormType={changeFormType}
registerHandler={registerHandler}/>
: <RegisterForm
changeHandler={changeHandler}
form={form}
changeFormType={changeFormType}
/>}
<h1 id="logreg-logo2"> Created by: <br /> <span id="logreg-logo-down2">PTN</span></h1>
</div>
);
}
export default AuthPage;

Onchange in React input causes the input to rerender on every letter

So I've created inputs in two functions and on Onchange it gets the value that is being input into them. But anytime I type into the inputs I can only type a letter at a time before it is unfocused and I believe this is because the component keeps on rendering.
I've also realized that whenever I remove the Onchange and value props then everything goes back to normal and I'm able to type everything easily. How would I fix this?
App.js
import style from "./auth.module.css";
import { useEffect, useRef, useState } from "react";
import { useAuthState } from 'react-firebase-hooks/auth';
import { auth, signInWithEmailAndPassword, signInWithGoogle, registerWithEmailAndPassword } from "../../firebase";
import { CSSTransition } from "react-transition-group";
function Auth() {
const [activeMenu, setActiveMenu] = useState("main");
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [user, loading, error] = useAuthState(auth);
const Emailform = () => {
return (
<div className={style.formBox}>
<label className={style.label}>Email:</label>
<form className={style.input}>
<input
type="email"
name="email"
required="true"
value={email}
onChange={(e) => setEmail(e.target.value)} />
</form>
</div>
);
}
const Passform = () => {
return (
<div className={style.formBox}>
<label className={style.label}>Password:</label>
<form className={style.input}>
<input
type="password"
name="password"
required="true"
value={password}
onChange={(e) => setPassword(e.target.value)} />
</form>
</div>
);
}
let domNode = useClickOutside(() => {
setActiveMenu(false);
});
return (
<div className={style.container}>
<Login />
<Signup />
</div>
);
function AuthType(props) {
return (
<a
href={props.link}
className={style.menuItem}
onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}
>
{props.children}
</a>
);
}
/* Login */
function Login() {
return (
<CSSTransition in={activeMenu === "main"} unmountOnExit timeout={500}>
<div ref={domNode}>
<div className={style.login}>
<h1 className={style.title}>Clip It</h1>
{/* Email and Password */}
<Emailform/>
<Passform/>
<div className={style.button}>
<input
type="submit"
value="Login"
onClick={() => signInWithEmailAndPassword(email, password)} />
<input
type="submit"
value="Login with Google"
onClick={signInWithGoogle} />
</div>
<div className={style.text}>
<p className={style.plink}>Forgot Password</p>
<div>
Need an account?
<AuthType goToMenu="Signup">click here</AuthType>
</div>
</div>
</div>
</div>
</CSSTransition>
);
}
function Signup() {
return (
<CSSTransition in={activeMenu === "Signup"} unmountOnExit timeout={500}>
<div ref={domNode}>
<div className={style.signUp}>
<div className={style.title}> Clip It</div>
<Form label="First Name" type="text" />
<Form label="Last Name" type="Text" />
<Form label="Email" type="email"/>
<Form label="Date of Birth" type="date" />
<Form label="Password" type="password"/>
<Form label="Confirm Password" type="password" />
<div className={style.button}>
<input type="submit" value="Sign Up" />
</div>
<div className={style.text}>
have an
<AuthType goToMenu="main"> account</AuthType>
</div>
</div>
</div>
</CSSTransition>
);
}
}
let useClickOutside = (handler) => {
let domNode = useRef();
useEffect(() => {
let clickListener = (event) => {
if (domNode.current && !domNode.current.contains(event.target)) {
handler();
}
};
document.addEventListener("mousedown", clickListener);
return () => {
document.removeEventListener("mousedown", clickListener);
};
});
return domNode;
};
function Form(props) {
return (
<div className={style.formBox}>
<label className={style.label}>{props.label}:</label>
<form className={style.input}>
<input
type={props.input}
name={props.input}
required="true" />
</form>
</div>
);
}
export default Auth;
Don't put your component definition inside the other component. If you do it, you create a new component at every render.
You need to work around to move Emailform, Passform to outside of Auth.
Checkout this sandbox to experiment
function Auth() {
// 🚫 the bad place to define components
const Emailform = () => {
...
}
// 🚫 the bad place to define components
const Passform = () => {
...
}
}

The input value codes refused to work in react js

What could be wrong with these codes? The input is not working once I add [event.target.name]. If I remove that line of codes, I can see the contents that I type inside the input box. The issue is that I want it to work with this code [event.target.name]. This will enable me pick each inputbox values as entered by the user. There are three input boxes and I need to capture the three values in my useState. Any help on how to write it better?
import React, { useState } from 'react';
import "./addbirthday.css";
import "./home.css";
export default function Addbirthday({setShowAdd}) {
const [inputDatas, setInputData] = useState([
{fullName: '', fullDate: '', relationship: ''}
]);
const handlePublish = () =>{
console.log("Hi ", inputDatas)
}
const handleChangeInput = (index, event) =>{
const values = [...inputDatas];
values[index][event.target.name] = event.target.value
setInputData(values)
}
return (
<div className="container">
<div className= { closeInput? "addContainer" :"addWrapper homeWrapper "}>
<i className="fas fa-window-close" onClick={closeNow} ></i>
{inputDatas.map((inputData, index)=> (
<div key={index} className="addbirth">
<label>Name</label>
<input type="text" name="Fname" placeholder='Namend' value=
{inputData.fullName} onChange = {event => handleChangeInput(index, event)} />
<label>Date</label>
<input type="date" placeholder='Date' name="fdate" value=
{inputData.fullDate} onChange = {event => handleChangeInput(index, event)} />
<label>Relationship</label>
<input type="text" placeholder='Friend' name="frelationship" value=
{inputData.relationship} onChange = {event => handleChangeInput(index, event)}/>
</div>
))}
<button className="addBtn" onClick={handlePublish} >Add</button>
</div>
</div>
)
}
You are not setting the name correctly
Change your input tags name to same as state object name meaning
<input name='fullname' />
I have modified your code a bit. Make it as your own and get it done
Upvote my answer if it helps
https://codesandbox.io/s/jolly-khayyam-51ybe?file=/src/App.js:0-1711
import React, { useState } from "react";
export default function Addbirthday({ setShowAdd }) {
const [inputDatas, setInputData] = useState([
{ Fname: "", fdate: "", frelationship: "" }
]);
const handlePublish = () => {
console.log("Hi ", inputDatas);
};
const handleChangeInput = (index, event) => {
const values = [...inputDatas];
values[index][event.target.name] = event.target.value;
setInputData(values);
console.log(values[index][event.target.name]);
};
return (
<div className="container">
<div className={"addContainer addWrapper homeWrapper"}>
<i className="fas fa-window-close"></i>
{inputDatas.map((inputData, index) => (
<div key={index} className="addbirth">
<label>Name</label>
<input
type="text"
name="Fname"
placeholder="Namend"
value={inputData.fullName}
onChange={(event) => handleChangeInput(index, event)}
/>
<label>Date</label>
<input
type="date"
placeholder="Date"
name="fdate"
value={inputData.fullDate}
onChange={(event) => handleChangeInput(index, event)}
/>
<label>Relationship</label>
<input
type="text"
placeholder="Friend"
name="frelationship"
value={inputData.relationship}
onChange={(event) => handleChangeInput(index, event)}
/>
</div>
))}
<button className="addBtn" onClick={handlePublish}>
Add
</button>
</div>
</div>
);
}

the state inside hooks are not updated for first time on form submit in react

I was trying to implement contactUS form in react using hooks.Contact us form is placed inside hooks.When I first submit the form the state in hooks are not updated ,when I click 2nd time states are set .and I am returning state to class component there api call are made.
//contactushook.js
import React, { useState } from 'react';
const ContactUshook = ({ parentCallBack }) => {
const [data, setData] = useState([]);
const handleSubmit = (event) => {
event.preventDefault();
setData({ name: document.getElementById('name').value, email: document.getElementById('email').value, message: document.getElementById('message').value });
console.log(data);
parentCallBack(data);
}
return <React.Fragment>
<div className="form-holder">
<form onSubmit={handleSubmit}>
<div>
<input id="name" type="text" placeholder="enter the name"></input>
</div>
<div>
<input id="email" type="email" placeholder="enter the email"></input>
</div>
<div>
<textarea id="message" placeholder="Type message here"></textarea>
</div>
<button type="submit" >Submit</button>
</form>
</div>
</React.Fragment >
}
export default ContactUshook;
//contactus.js
import React, { Component } from 'react';
import ContactUshook from './hooks/contactushook';
import '../contactUs/contactus.css';
class ContactComponent extends Component {
onSubmit = (data) => {
console.log('in onsubmit');
console.log(data);
}
render() {
return (
<div>
<h4>hook</h4>
<ContactUshook parentCallBack={this.onSubmit}></ContactUshook>
</div>
);
}
}
export default ContactComponent;
Stop using document queries and start using state instead!
Your ContactUshook component should look like this:
const ContactUshook = ({ parentCallBack }) => {
const [data, setData] = useState({ name: '', email: '', message: '' });
const handleSubmit = () => {
event.preventDefault();
parentCallBack(data);
}
const handleChange = (event, field) => {
const newData = { ...data };
newData[field] = event.target.value;
setData(newData);
}
return (
<div className="form-holder">
<form onSubmit={handleSubmit}>
<div>
<input
id="name"
type="text"
value={data.name}
placeholder="enter the name"
onChange={(e) => handleChange(e,'name')} />
</div>
<div>
<input
id="email"
type="email"
value={data.email}
placeholder="enter the email"
onChange={(e) => handleChange(e,'email')} />
</div>
<div>
<textarea
id="message"
value={data.message}
placeholder="Type message here"
onChange={(e) => handleChange(e,'message')} />
</div>
<button type="submit" >Submit</button>
</form>
</div>
);
}

Resources