First this is my parent component :
import React from 'react'
import logo from '../Assets/LOGO.png'
import EmailInput from '../Components/LoginPage/EmailInput'
import PasswordInput from '../Components/LoginPage/PasswordInput'
import Rememberme from '../Components/LoginPage/Rememberme'
import SigninInput from '../Components/LoginPage/SigninInput'
import '../Styles/Login/login.css'
function Login() {
return (
<main>
<div className='top'>
<img src={logo} alt='Netflix' />
</div>
<section>
<div className='si-card'>
<h2>Sign In</h2>
<EmailInput />
<PasswordInput />
<SigninInput />
<Rememberme />
</div>
</section>
</main>
)
}
export default Login
PasswordInput
:
import React from 'react'
function PasswordInput() {
const passwordRef = React.useRef()
function passwordValidation() {
let value = passwordRef.current.value
if (value.length <= 6) {
console.log('Password must be smaller than 4 charectar')
}
}
return (
<div className='input-co'>
<input
type='password'
id='password'
placeholder=' '
onChange={passwordValidation}
ref={passwordRef}
/>
<label htmlFor='password'>Password</label>
</div>
)
}
export default PasswordInput
EmailInput
:
import React from 'react'
function EmailInput() {
const reg = /^\w ([\\.-]?\w )*@\w ([\\.-]?\w )*(\.\w{2,3}) $/
const emailRef = React.useRef()
function emailValidation() {
let value = emailRef.current.value
if (!reg.test(value)) {
console.log('Enter a valid email')
}
}
return (
<div className='input-co'>
<input
type='email'
id='email'
placeholder=' '
onChange={emailValidation}
ref={emailRef}
/>
<label htmlFor='email'>Email or phone number</label>
</div>
)
}
export default EmailInput
SigninInput
:
import React from 'react'
function SigninInput() {
return <button className='signin'>Sign in</button>
}
export default SigninInput
How can I pass ref from EmailInput
and passwordInput
to SigninInput
?
I want access to a value of two input when user is clicked on sign in button
CodePudding user response:
The usual flow of React is passing values as props down to children. You can't directly pass anything between siblings. You can, however, control the state in the parent component or a parent context and, from there, send the data down as props to the component that requires them.
I would structure your app using Login as a parent that handles the values for EmailInput and PasswordInput as state.
Login:
function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
function handleEmailChange(value) {
setEmail(value);
}
function handlePasswordChange(value) {
setPassword(value);
}
function handleSignIn() {
// use the values here
}
return (
<main>
<div className="top">
<img src={logo} alt="Netflix" />
</div>
<section>
<div className="si-card">
<h2>Sign In</h2>
<EmailInput onChange={handleEmailChange} />
<PasswordInput onChange={handlePasswordChange} />
<button className="signin" onClick={handleSignIn}>
Sign in
</button>
<Rememberme />
</div>
</section>
</main>
)
}
PasswordInput:
function PasswordInput({ onChange }) {
const passwordRef = React.useRef()
function passwordValidation() {
let value = passwordRef.current.value
if (value.length <= 6) {
console.log("Password must be smaller than 4 charectar")
}
onChange(value)
}
return (
<div className="input-co">
<input type="password" id="password" placeholder=" " onChange={passwordValidation} ref={passwordRef} />
<label htmlFor="password">Password</label>
</div>
)
}
export default PasswordInput
EmailInput:
function EmailInput({ onChange }) {
const reg = /^\w ([\\.-]?\w )*@\w ([\\.-]?\w )*(\.\w{2,3}) $/
const emailRef = React.useRef()
function emailValidation() {
let value = emailRef.current.value
if (!reg.test(value)) {
console.log("Enter a valid email")
}
onChange(value)
}
return (
<div className="input-co">
<input type="email" id="email" placeholder=" " onChange={emailValidation} ref={emailRef} />
<label htmlFor="email">Email or phone number</label>
</div>
)
}
export default EmailInput
CodePudding user response:
- It would be better to use
state
than usetemplate refs
to get the inputs values. - In this case, you need to store your inputs state in the parent component and pass them as props to the child components.
import React from 'react'
import logo from '../Assets/LOGO.png'
import EmailInput from '../Components/LoginPage/EmailInput'
import PasswordInput from '../Components/LoginPage/PasswordInput'
import Rememberme from '../Components/LoginPage/Rememberme'
import SigninInput from '../Components/LoginPage/SigninInput'
import '../Styles/Login/login.css'
function Login() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = () => {
console.log('email: ' email);
console.log('password: ' password);
}
return (
<main>
<div className='top'>
<img src={logo} alt='Netflix' />
</div>
<section>
<div className='si-card'>
<h2>Sign In</h2>
<EmailInput email={email} setEmail={setEmail} />
<PasswordInput password={password} setPassword={setPassword} />
<SigninInput handleSubmit={handleSubmit} />
<Rememberme />
</div>
</section>
</main>
)
}
export default Login
PasswordInput:
import React from 'react'
function PasswordInput({ password, setPassword }) {
function passwordValidation(e) {
const value = e.target.value
setPassword(value)
if (value.length <= 6) {
console.log('Password must be smaller than 4 charectar')
}
}
return (
<div className='input-co'>
<input
type='password'
id='password'
placeholder=''
value={password}
onChange={passwordValidation}
/>
<label htmlFor='password'>Password</label>
</div>
)
}
export default PasswordInput
EmailInput:
import React from 'react'
function EmailInput({ email, setEmail }) {
const reg = /^\w ([\\.-]?\w )*@\w ([\\.-]?\w )*(\.\w{2,3}) $/
function emailValidation(e) {
const value = e.target.value
setEmail(value)
if (!reg.test(value)) {
console.log('Enter a valid email')
}
}
return (
<div className='input-co'>
<input
type='email'
id='email'
placeholder=' '
value={email}
onChange={emailValidation}
/>
<label htmlFor='email'>Email or phone number</label>
</div>
)
}
export default EmailInput
SigninInput:
import React from 'react'
function SigninInput({ handleSubmit }) {
return <button className='signin' onClick={handleSubmit}>Sign in</button>
}
export default SigninInput
CodePudding user response:
Initialize the ref variables in the parent level and pass them to child as props through forward ref
function Login() {
const emailRef = React.useRef()
const passwordRef = React.useRef()
return (
<main>
<div className='top'>
<img src={logo} alt='Netflix' />
</div>
<section>
<div className='si-card'>
<h2>Sign In</h2>
<EmailInput ref={emailRef} />
<PasswordInput ref={passwordRef} />
<SigninInput email={emailRef.current.value} password={passwordRef.current.value} />
<Rememberme />
</div>
</section>
</main>
)
}
export default EmailInput = React.forwardRef((ref) =>{ ....
function SigninInput({email = "",password = ""}) { ...