React refuses to keep focus on input field while typing.
I've tried to fix it, but was not successful. I don't understand this behaviour.
This is the component:
import React, { useState } from 'react'
import styled from 'styled-components'
const Auth = () => {
const Form = styled.form``
const InputGroup = styled.div``
const Input = styled.input``
const Button = styled.button``
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
return (
<Form>
<InputGroup>
<Input
value={email}
onChange={event => {
setEmail(event.target.value)
}}
type="email"
/>
</InputGroup>
<InputGroup>
<Input
value={password}
onChange={event => {
setPassword(event.target.value)
}}
type="password"
/>
</InputGroup>
<Button />
</Form>
)
}
export default Auth
codesandbox working example of the problem
the problem is you are defining Input component inside your function which create new element each time so your new input lost focus.
to fix problem define your component outside function.
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import styled from "styled-components";
const Form = styled.form``;
const InputGroup = styled.div``;
const Input = styled.input``;
const Button = styled.button``;
const Auth = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
return (
<Form>
<InputGroup>
<Input
value={email}
onChange={event => {
setEmail(event.target.value);
}}
type="email"
/>
</InputGroup>
<InputGroup>
<Input
value={password}
onChange={event => {
setPassword(event.target.value);
}}
type="password"
/>
</InputGroup>
<Button>press me</Button>
</Form>
);
};
function App() {
return (
<div className="App">
<Auth />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Related
Not working onChange in react-input-mask (custom input)
I am not using any libraries as input, but for some reason onChange dont work...
<InputMask
onChange={(e) => console.log(e.target.value)} // dont work...
disabled={true}
>
{(props) => {
return <input type="text" />;
}}
</InputMask>
you need to pass props inside custom input
import React from "react";
import { useState } from "react";
import ReactDOM from "react-dom";
import InputMask from "react-input-mask";
import "./styles.css";
const App = () => {
const [inputValue, setInputValue] = useState("");
const onHandleChange = (event) => {
console.log(event.target.value);
setInputValue(event.target.value);
};
return (
<div className="App">
<h1>react-input-mask with Input from Ant D</h1>
<h2>
Throwing error: react-input-mask: the following props should be passed
to the react-input-mask's component and should not be altered in
children's function: disabled
</h2>
<InputMask mask="99/99/9999" value={inputValue} onChange={onHandleChange}>
{(inputProps) => (
<input {...inputProps} type="tel" className="" disableUnderline />
)}
</InputMask>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Hello I'mm new to coding and I want to make my signin function using redux, but I have a problem with my code. I'm getting the error:
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
This is my code
import React, { useEffect, useState } from 'react'
import { Button, Container, Form } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
import ErrorMessageBox from '../components/ErrorMessagebox'
import Loading from '../components/Loading'
export const SignInScreen = () => {
const navigate = useNavigate
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { search } = useLocation()
const redirectInUrl = new URLSearchParams(search).get('redirect')
const redirect = redirectInUrl ? redirectInUrl : '/'
const userLogin = useSelector((state) => state.userLogin)
const { userInfo, loading, error } = userLogin
const dispatch = useDispatch()
useEffect(() => {
if (userInfo) {
navigate(redirect)
}
}, [navigate, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
return (
<Container className="small-container">
<h1 className="my-3">Sign In</h1>
{error && <ErrorMessageBox variant="danger">{error}</ErrorMessageBox>}
{loading && <Loading />}
<Form onSubmit={submitHandler}>
<Form.Group className="mb-3" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
required
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="password">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
required
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<div className="mb-3">
<Button type="submit">Sign In</Button>
</div>
<div className="mb-3">
New Customer?{' '}
<Link to={`/signup?redirect=${redirect}`}>Create new account</Link>
</div>
</Form>
</Container>
)
}
When I run npm ls react-dom, it shows
Plesae help, I don't know what this error means.
Sir. I think you made a typo and the error is due to that.
Change useNavigate to useNavigate()
import React, { useEffect, useState } from 'react'
import { Button, Container, Form } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'
import ErrorMessageBox from '../components/ErrorMessagebox'
import Loading from '../components/Loading'
export const SignInScreen = () => {
const navigate = useNavigate()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const { search } = useLocation()
const redirectInUrl = new URLSearchParams(search).get('redirect')
const redirect = redirectInUrl ? redirectInUrl : '/'
const userLogin = useSelector((state) => state.userLogin)
const { userInfo, loading, error } = userLogin
const dispatch = useDispatch()
useEffect(() => {
if (userInfo) {
navigate(redirect)
}
}, [navigate, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
return (
<Container className="small-container">
<h1 className="my-3">Sign In</h1>
{error && <ErrorMessageBox variant="danger">{error}</ErrorMessageBox>}
{loading && <Loading />}
<Form onSubmit={submitHandler}>
<Form.Group className="mb-3" controlId="email">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
required
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="password">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
required
onChange={(e) => setPassword(e.target.value)}
/>
</Form.Group>
<div className="mb-3">
<Button type="submit">Sign In</Button>
</div>
<div className="mb-3">
New Customer?{' '}
<Link to={`/signup?redirect=${redirect}`}>Create new account</Link>
</div>
</Form>
</Container>
)
}
I have a super simple form I'm trying to test with react testing library
The form is like
import React, { useState } from 'react';
import './App.css';
function App() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
return (
<div className="App">
<form>
<label htmlFor="email">Email</label>
<input
type="email"
id="email"
name="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
name="password"
value={password}
onChange={e => setPassword(e.target.value)}
/>
</form>
</div>
);
}
export default App;
And simple trying to test the input with
test('should be able to type an email', () => {
render(<App />)
const emailInput = screen.getByRole('textbox', {name: /email/i})
userEvent.type(emailInput, 'test#email.com')
expect(emailInput.value).toBe('test#email.com')
})
But this errors at emailInput.value saying
Property 'value' does not exist on type 'HTMLElement'.
I'm using typescript in the app, is this to do with types. How can I fix this
const emailInput = screen.getByRole<HTMLInputElement>('textbox', {name: /email/i}) should work in your case
It gives an error i do not know why, If you look my codes, there is not any problem you will see.
Login Route page:
const [email, setEmail] = useState("");
<LoginPage
email={email}
setEmail={setEmail} />
Login Form codes:
const {
email,
setEmail,
} = props;
<input
type="email"
className="form-control"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
Login Page Component
<LoginPage />
Login Form Component
import React, { useState } from "react";
const LoginForm = (props) => {
const [email, setEmail] = useState("");
return (
<>
<input
type="email"
className="form-control"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{/* Other components */}
</>
);
};
I'm using bootstrap-validate for my forms, and I'm running into a really weird problem. If I try to use setIsValidEmail in the callback then whenever I type [some-text]#[some-text].com . I can't type anything pass the 'c' in 'com'. It works fine if I leave the callback and just remove setIsValidEmail.
Repo: https://github.com/mlelien/testtest
import React, { useState } from 'react'
import * as bootstrapValidate from 'bootstrap-validate'
window.bootstrapValidate = bootstrapValidate
const SignUp2 = () => {
const [email, setEmail] = useState('')
const [isValidEmail, setIsValidEmail] = useState(false)
const onEmailChange = (e) => {
const newEmail = e.target.value
setEmail(newEmail)
bootstrapValidate('#form-email', 'email:Invalid email', (isValid) => {
setIsValidEmail(isValid)
})
}
return (
<div className="container">
<h3>SIGN UP</h3>
<form>
<div className="form-group">
<label htmlFor="form-email">
Email address
<input
type="email"
className="form-control"
id='form-email'
aria-describedby='enter email'
placeholder='Enter email'
value={email}
onChange={onEmailChange}
/>
</label>
</div>
</form>
</div>
)
}
export default SignUp2