Not working onChange in react-input-mask (custom input) - reactjs

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);

Related

How to prevent re-rendering on onChange Event of input field

/**
Make sure we keep the same functionality, without causing a re-render
on every keypress when typing in the input.
*/
import React, { useState } from "react";
export const Example: React.FC = () => {
const [userInput, setUserInput] = useState("");
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setUserInput(event.target.value);
}
console.log("Example renders");
return (
<>
<h1>Send us some feedback</h1>
<div>
<input type="text" onChange={handleChange} value={userInput} />
<button
type="submit"
onClick={() => {
alert(userInput);
}}
>
Submit
</button>
</div>
</>
);
};

Input value is showing undefined (reading 'value') while using rsuite library

It is basically rsuite#4.10.2 version
const [user, setuser] = useState('')
<InputGroup>
<Input type='text' value={user} onChange={e=>{setuser(e.target.value)}} id="user"/>
<InputGroup.Button>
<Icon icon="user" />
</InputGroup.Button>
</InputGroup>
also i have provided with the error image just look this out
enter image description here
rsuite library return the value directly in the onChange function.
So, instead:
onChange={e=>{setuser(e.target.value)}}
You should write
onChange={value=>{setuser(value)}}
This is a class that I have written with rsuite / bootstrap and basic input. You can see the difference and copy/paste the part that you want.
import React, { useState } from 'react';
import { InputGroup, Input } from 'rsuite';
import InputGroupBoostrap from 'react-bootstrap/InputGroup';
import FormControlBoostrap from 'react-bootstrap/FormControl';
const Question2 = () => {
const [user, setUser] = useState('example');
return (
<>
{/* rsuite */}
<InputGroupBoostrap>
<Input type='text' value={user} onChange={value=>{ setUser(value)}} id="user"/>
<InputGroup.Button>
Button
</InputGroup.Button>
{/* Bootstrap */}
</InputGroupBoostrap>
<InputGroupBoostrap>
<InputGroupBoostrap.Text>User 1</InputGroupBoostrap.Text>
<FormControlBoostrap value={user} onChange={(e) => { setUser(e.target.value); }} placeholder="user" />
</InputGroupBoostrap>
{/* input */}
<div>
<span>User 2</span>
<input value={user} onChange={(e) => { setUser(e.target.value); }}/>
</div>
</>
);
}
export default Question2;
I hope I've helped

How to get the initial validation message from Input in React?

I have a number input (using Material UI Input) with min max set. If a user types in a number higher than the max, I can get the validation message from event.target.validationMessage during onChange event. This works so far when a user is inputting on an empty number input field.
Now say I initialised my state with an initial value that is higher than the max already, how and when should I access the event.target.validationMessage as this is before the user input (i.e. no onChange event yet)?
Here is an example: https://codesandbox.io/s/cocky-shamir-1fg7h
import { useState } from "react";
import ReactDOM from "react-dom";
const Input = (props) => {
const [msg, setMsg] = useState();
return (
<div>
<input
type="number"
min="1"
max="10"
defaultValue={props.defaultValue}
onChange={(event) => setMsg(event.target.validationMessage)}
></input>
<span>{msg}</span>
</div>
);
};
const App = () => {
return (
<div>
<label>Type 0 below to see the error message</label>
<Input defaultValue="1" />
<label>Should show error message straight away</label>
<Input defaultValue="100" />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
This should do the trick (or at least be a start):
import { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
const Input = (props) => {
const [msg, setMsg] = useState();
// the added part
const ref = useRef();
useEffect(() => {
if (ref.current.validationMessage) setMsg(ref.current.validationMessage);
}, [ref]);
// the added part
return (
<div>
<input
ref={ref}
type="number"
min="1"
max="10"
defaultValue={props.defaultValue}
onChange={(event) => setMsg(event.target.validationMessage)}
></input>
<span>{msg}</span>
</div>
);
};
const App = () => {
return (
<div>
<label>Type 0 below to see the error message</label>
<Input defaultValue="1" />
<label>Should show error message straight away</label>
<Input defaultValue="100" />
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
codesandbox
Remember that target is basically a ref to your input.

Use react-input-mask with antd in react-final-form

I would like to use react-input-mask with Ant Design Input in react-final-form. In order to use antd with react-final-form I also had to install redux-form-antd. So the file looks like this:
import React from "react";
import ReactDOM from "react-dom";
import { Button } from "antd";
import { Form, Field } from "react-final-form";
import InputMask from "react-input-mask";
import { TextField } from "redux-form-antd";
import "antd/dist/antd.css";
const onSubmit = async values => {
window.alert(JSON.stringify(values, 0, 2));
};
const Input = props => <InputMask {...props} />;
function App() {
return (
<Form
onSubmit={onSubmit}
render={({ handleSubmit, values }) => (
<form onSubmit={handleSubmit}>
<Field
name="mask"
parse={value =>
value
.replace(/\)/g, "")
.replace(/\(/g, "")
.replace(/-/g, "")
.replace(/ /g, "")
}
render={({ input, meta }) => (
<div>
<label>mask phone</label>
<Input mask="+7 (999) 999-99-99" {...input} />
{meta.touched && meta.error && <span>{meta.error}</span>}
</div>
)}
/>
<Field
name="antd"
component={TextField}
label="antd phone"
placeholder="Phone"
/>
<Button className="submit-button" type="primary">
Send
</Button>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is a codesandbox example.
I could only get to work a regular input with an InputMask (input 1) or an antd input without a mask (input 2).
How can I add an InputMask to antd input?
I've managed to use react-input-mask with antd and react-final-form without any external libraries.
Here is my component:
import React from "react";
import InputMask from "react-input-mask";
import { Input } from "antd";
import FormItem from "antd/lib/form/FormItem";
const MaskInput = props => {
const { disabled, mask, label, meta, required } = props;
return (
<FormItem
label={label}
validateStatus={
meta.touched ? (meta.error ? "error" : "success") : undefined
}
help={meta.touched ? (meta.error ? meta.error : undefined) : undefined}
hasFeedback={meta.touched ? true : false}
required={required}
>
<InputMask
mask={mask}
disabled={disabled}
autoComplete="off"
{...props.input}
>
<Input />
</InputMask>
</FormItem>
);
};
export default MaskInput;
Then it is passed to the component prop of the Field:
<Field
name="phone"
label="Phone"
component={MaskInput}
mask="+7 (999) 999-99-99"
required
/>
Here is the link to the codesandbox example.
I've never used either of those libraries, but you might want to check out using format-string-by-pattern with react-final-form's built-in parsing and formatting functionality to achieve a similar thing.
I bet you could throw redux-form-antd components into here pretty easily...

React Unfocuses Input Field When Typing

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);

Resources