GoncharukOrg / react-input

109 stars 9 forks source link

useNumberFormat doesn't apply the mask when on first render, only after editing #4

Closed pyrexfm closed 1 year ago

pyrexfm commented 1 year ago

Example code:

`import { useState, type ChangeEvent } from "react"; import { useNumberFormat } from "@react-input/number-format";

export type BalanceInputProps = { date: Date; balance: number; onChange: (date: Date, value: number) => void; };

export function BalanceInput({ date, balance, onChange }: BalanceInputProps) { const [value, setValue] = useState(balance.toString()); const ref = useNumberFormat({ locales: "en", maximumFractionDigits: 2 });

const handeChange = (event: ChangeEvent) => { const { value } = event.target;

setValue(value);

};

return ; } `

GoncharukBro commented 1 year ago

To ensure consistency between what you store in external state and what you see in the InputNumberFormat/useNumberFormat interface, it will not itself change the value passed in the value or defaultValue property of the input element, nor will it intentionally call input event handlers, outside of their flow of work, so you need to specify as an initialized value one that can match the formatted value at any stage of the input. You can do this by using the Intl.NumberFormat constructor when initializing the state with the parameters passed to useNumberFormat:

const [value, setValue] = useState(() => Intl.NumberFormat("en", { maximumFractionDigits: 2 }).format(balance));
const ref = useNumberFormat({ locales: "en", maximumFractionDigits: 2 });

If you make a mistake, you will see a warning about it in the console.

Quote from README - https://github.com/GoncharukBro/react-input/tree/main/packages/number-format#usage

pyrexfm commented 1 year ago

Thank you, missed that!