Closed lisandro52 closed 1 year ago
I reproduced the hook example and didn't see an error in the console, but you can use the following Material UI integrations to be able to set the mask in an external component:
1) Hook
import { forwardRef } from "react";
import { useMask, MaskProps } from "@react-input/mask";
import TextField, { TextFieldProps } from "@mui/material/TextField";
type InputProps = TextFieldProps &
Pick<MaskProps, "mask" | "replacement"> & { loading?: boolean };
const Input = forwardRef<HTMLDivElement, InputProps>(
(
{
loading=false
disabled=false
InputProps,
mask,
replacement,
...props
},
ref
) => {
const maskRef = useMask({ mask, replacement });
return (
<TextField
ref={ref}
fullWidth
variant="standard"
autocomplete="off"
disabled={disabled || loading}
inputRef={maskRef}
InputProps={{
...InputProps,
readOnly: InputProps?.readOnly || loading
}}
{...props}
/>
);
}
);
export default function App() {
return <Input mask="___-___" replacement="_" />;
}
2) Input Component
import { forwardRef } from "react";
import { InputMask, MaskProps } from "@react-input/mask";
import TextField, { TextFieldProps } from "@mui/material/TextField";
type InputProps = TextFieldProps &
Pick<MaskProps, "mask" | "replacement"> & { loading?: boolean };
const Input = forwardRef<HTMLDivElement, InputProps>(
(
{
loading=false
disabled=false
InputProps,
mask,
replacement,
...props
},
ref
) => {
return (
<TextField
ref={ref}
fullWidth
variant="standard"
autocomplete="off"
disabled={disabled || loading}
InputProps={{
...InputProps,
readOnly: InputProps?.readOnly || loading,
inputComponent: InputMask,
inputProps: { mask, replacement }
}}
{...props}
/>
);
}
);
export default function App() {
return <Input mask="___-___" replacement="_" />;
}
The organization of properties is up to you, but the principle of use remains the same.
Thanks for highlighting the inaccurate point from the documentation, I'll be sure to update the README to make using the library easier.
Please provide feedback if possible.
Hi! Thank you so much for replying to my issue. When I saw that you couldn't reproduce the error, I tried creating a clean repo to showcase the error but... I can't actually replicate it, so I'm guessing there is something else here.
One crucial bit of info I missed on my original issue is that I'm also using react-hook-form
together with the rest, and RHF is the one sending a ref... but again, it's odd, because the ref from RHF is the one that gets passed to the TextField
and it has nothing to do with the inputRef
or the useMask
hook...
I think it has to do with the React.StrictMode
and some other library, like react-router
for example - while mounting/unmounting, the current ref gets lost somehow and it triggers that warning . Thankfully, it won't appear on production but it still is odd.
Anyway, while trying to replicate the error I found another thing: if you make the parameters mask
and replacement
optionals, and you pass undefined
, i.e. you don't use the props, the input stops working completely. I had to do a hack to stop using the maskRef
in case there is no mask defined.
inputRef={mask === undefined ? undefined : maskRef}
Is this the intended functionality?
I've now found the problem. I think it was, partially, due to my hack above. The ref is never set, so it never leaves the 'null' state and it throws the warning on the console. If I remove my hack, the warning doesn't appear, but the input stops working because there is no mask... It was all connected after all.
Please send me a complete code example so I can reproduce the problem.
Please send me a complete code example so I can reproduce the problem.
I could finally reproduce it on my brand new repo. Here is the link, and thank you again for taking the time. https://github.com/lisandro52/react-input-bug
yarn && yarn dev
I looked at your code and there is no error in it. The component or hook only uses formatted input, which means that if you don't pass in a mask value, then the (default) mask will be an empty string, which provides no replacement characters, meaning no input will be taken.
If you have a need to enter any character without passing a mask, you must check for the presence of the mask and substitute either the mask input component or the arbitrary input component. You have already used a similar approach in HackedTextWithHook
.
Tell me, do you see the implementation, in which arbitrary input will be carried out without a mask, useful?
If you have a need to enter any character without passing a mask, you must check for the presence of the mask and substitute either the mask input component or the arbitrary input component. You have already used a similar approach in
HackedTextWithHook
.
Yes, exactly, I think the solution should be this, but in development mode, there is an error popping up on the console and it's distracting. It's exactly this line that pops up.
Just making the console.error
into a console.warn
would be enough.
Perhaps using warn
instead of error
would actually be more appropriate. Thanks for the feedback!
Hi! First of all, thank you for your library, it's the first one that I see that has a simple yet powerful solution for masking an input.
I'm having a problem, though, with using the MUI TextField with react-input/mask. I'm sorry I don't have a codesandbox, but I couldn't install @react-input/mask there. I've tried using your example from the docs, where you pass a CustomInputMask, but the problem is that I also need to pass the properties mask and replacement, because I don't want my dev-user to directly work with InputMask, I just want them to give me the mask and I'll handle the rest.
I tried defining the function right there but it's obviously re-rendering every time and it's impossible to type. I've also tried using a useMemo to create the CustomInputMask only when either the mask or replacement changes (using json-deterministic-stringify to avoid passing an object as a dependency), but that didn't work either.
Finally I tried simply using the useMask hook and passing down the inputRef to the TextField, and that's working ok! But for some reason, there is a console.error saying that the inputRef is null, and it doesn't look good...
This is my latest working code
If you need more info, just let me know. Thanks!