Minlength doesn't work when I add onChange property - reactjs

I want to prevent using special symbols except - in input and check the min-length and max-length. But When I add onChange property on input tag, the minLength property doesn't work!(maxLength works fine.)
Does anyone how to solve this?
const handleNickname = (e: React.ChangeEvent<HTMLInputElement>) => {
let allowedNick = e.target.value;
allowedNick = allowedNick.replace(/ /gi, "");
allowedNick = allowedNick.replace(
/[~\-+=!?##$%₩^&*|(){}\[\]\\\/'";:<>,]/gi,
""
);
e.target.value = allowedNick;
setNick(allowedNick);
};
<form>
<input type="text" placeholder="text" required={true} minLength={2} maxLength={10} onChange={handleNickname} />
<button type="submit">Submit</button>
</form>

You are manually changing the value, and for some reason this is messing with the form submission validator.
This line breaks - e.target.value = allowedNick;
Making component controlled solved this for me.
export function Test() {
const [text, setText] = useState('') // added state
const handleNickname = (e) => {
let allowedNick = e.target.value;
allowedNick = allowedNick.replace(/ /gi, "");
allowedNick = allowedNick.replace(
/[~\-+=!?##$%₩^&*|(){}\[\]\\\/'";:<>,]/gi,
""
);
setText(allowedNick) // changing state
};
return <form>
<input type="text" placeholder="text" onChange={handleNickname} required={true} minLength={2} maxLength={10} value={text} />
<button type="submit">Submit</button>
</form>
}

Related

Why do I need a separate handler from checked input?

Unable to get the value of the checked input (true or false).
function Login() {
const [inputs, setInputs] = useState({});
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
setInputs(values => ({
...values,
[name]: value
}));
};
const handleSubmit = (event) => {
event.preventDefault();
console.log({inputs});
};
return (
<form onSubmit={handleSubmit}>
<input type="email" name="mail" value={inputs.mail || ""} onChange={handleChange}/>
<input type="password" name="pass" value={inputs.pass || ""} onChange={handleChange}/>
<div>
<input type="checkbox" name="check" value={inputs.check || false} onChange={handleChange}/>
<label>Remember me</label>
</div>
<button type="submit">Submit</button>
</form>
);
}
export default LoginGoogle
Tried
const handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
const check = event.target.checked;
setInputs(values => ({
...values,
[name]: value || check
}));
};
For
<input type="checkbox" name="check" value={inputs.checked} onChange={handleChange}/>
And
<input type="checkbox" name="check" checked={inputs.checked} onChange={handleChange}/>
It works, but I am certain I am going about it wrong. Tutorials seem to concentrate on input objects of similar key-values, e.g. multiple checkboxes, multiple text input, and so on.
The reason is that checkbox values never change, only their checked property does.
Ideally, you'd use a different change handler
const onCheckboxChange = ({ target: { name, checked } }) => {
setInputs((prev) => ({
...prev,
[name]: checked,
}));
};
return (
<input
type="checkbox"
name="check"
checked={inputs.check}
onChange={onCheckboxChange}
/>
);

Input value is not being cleared after submit

I am building a to-do list in react and when adding a new task to the list, the input value is not being cleared from the form after submit, I'm trying to achieve this using setInput('');
const Form = (props) => {
const [input, setInput] = useState('');
const handleChange = e => {
setInput(e.target.value);
}
const handleSubmit = e => {
e.preventDefault();
const newTask = {
id: uuidv4(),
text: input,
completed: false
};
props.onSubmit(newTask);
setInput('');
}
return (
<form
className='task-form'
>
<input
className='task-input'
type='text'
placeholder='Enter a task'
name='text'
onChange={handleChange}
/>
<button className='task-btn' onClick={handleSubmit}>Add Task</button>
</form>
)
}
export default Form
You aren't using the input state anywhere except when creating the newTask object. You need to pass it as a prop to the <input> component to make it fully controlled and for calls to the state setter to result in changes to the DOM.
<input
className='task-input'
type='text'
placeholder='Enter a task'
name='text'
onChange={handleChange}
/>
should be
<input
className='task-input'
type='text'
placeholder='Enter a task'
name='text'
onChange={handleChange}
value={input}
/>

Dont set value in Form.Control

I have a new form for save data.
I use this code
const [validated, setValidated] = useState(false);
const [newInfo, setNewInfo] = useState({
name: ""
});
const handleChange = (event) => {
const { name, value }=event.target.value;
setNewInfo({
...newInfo,
[name]: value
});
console.log(newInfo.name)
};
and in Form.Control
<Form noValidate validated={validated}>
<Form.Group >
<Form.Label>Name</Form.Label>
<Form.Control required type="text" placeholder="Enter Name" value={newInfo.name}
onChange={handleChange} />
<Form.Control.Feedback type="invalid">Please choose a name.</Form.Control.Feedback>
</Form.Group>
<Button onClick={(e) => handleSubmit(e)} variant="primary">Submit</Button>
</Form>
When i type in input, run onchangehandle and event.target.value has value but dont set in input (input is empty) !!
when i change const [newInfo, setNewInfo] = useState(""); and set a string for it, it is ok .
setNewInfo() which is a setter is asynchronous, which means that at the time you console.log the state, it's not updated yet.
You can use useEffect to track for changes of state.
useEffect(() => {
console.log(newInfo);
},[newInfo.name);

Change input values bases on other input onChange

Let's say I want to create a Converter, which means the input value should be changed based on another one.
just to see what I want to do in action https://calolocosta.github.io/romanNumeralsConverter/.
here's what I tried so far but couldn't make it
function LightBulb() {
let [input1, setInput1] = useState("");
let [input2, setInput2] = useState("");
const handleInput1 = (e) => {
setInput2(e.target.value);
};
const handleInput2 = (e) => {
setInput1(e.target.value);
};
return (
<div className="App">
<input
type="text"
value={input2}
onChange={(e) => handleInput1(e)}
placeholder="example 1000"
/>
<input
type="text"
value={input1}
onChange={(e) => handleInput2(e)}
placeholder="example MCMXC"
/>
</div>
);
}
so what I want is to change the input2 value when input1 is typing and vice versa.
Here's the codesandbox that I have been working on: https://codesandbox.io/s/react-hooks-usestate-forked-8o257, any idea would appreciate it.
I guess you will do the rests of the logic for that conversion. But as far as the inputs go and their interaction that needs to change the other one, here is the code changed:
function LightBulb() {
let [input1, setInput1] = useState("");
let [input2, setInput2] = useState("");
const handleInput1 = (e) => {
setInput1(e.target.value);
setInput2("Converted value");
};
const handleInput2 = (e) => {
setInput2(e.target.value);
setInput1("Converted value");
};
console.log(input2);
return (
<div className="App">
<input
type="text"
value={input1}
onChange={(e) => handleInput1(e)}
placeholder="example 1000"
/>
<input
type="text"
value={input2}
onChange={(e) => handleInput2(e)}
placeholder="example MCMXC"
/>
</div>
);
}
You need to set value for corresponding input anyways. But value for the counterpart needs to be set with converted value.
Here is codesandbox also: https://codesandbox.io/s/react-hooks-usestate-forked-667fr?file=/src/index.js:100-777

Clear value into input using useState or useRef (React)

I got hook:
const [myName, setMyName] = useState("");
const myNameRef = useRef();
Then I have form:
<form onSubmit={(e) => addVist(e, user.id)}>
<input type="text" name="myName" ref={myNameRef} onChange={e => setMyName(e.target.value)} />
<input type="submit" value="Run" />
</form>
And method:
const addVist = (e, userId) => {
e.preventDefault();
console.log(myName)
//some code....
//clear value form
setMyName("");
//setMyName('');
//setMyName(e.target.value = "");
//myNameRef.current.value("");
}
But the setMyName("") is not working - still I see value inside input.
You missed binding myName as value attribute of the input tag.
<input type="text" name="myName" value={myName} ref={myNameRef} onChange={e => setMyName(e.target.value)} />
Here is a complete example of clearing input using state OR a reference:
export default function App() {
const [value, setValue] = useState("");
const inputRef = useRef();
return (
<>
<input value={value} onChange={(e) => setValue(e.target.value)} />
<input ref={inputRef} />
<button
onClick={() => {
setValue("");
inputRef.current.value = "";
}}
>
Clear
</button>
</>
);
}
Refer to Controlled VS Uncontrolled components.
On your text input you should pass myName into the value attribute like so
<input type="text" name="myName" value={myName} ref={myNameRef} onChange={e => setMyName(e.target.value)} />
You forgot to add myName as value.
<input type="text" name="myName" value={myName} ref={myNameRef} onChange={e => setMyName(e.target.value)} />

Resources