@@ -65,9 +65,13 @@ export const CharacterCount = ({
6565 getMessage = defaultMessage ,
6666 ...remainingProps
6767} : TextInputCharacterCountProps | TextareaCharacterCountProps ) : JSX . Element => {
68- const initialCount = getCharacterCount ( value || defaultValue )
68+ const [ initialCount ] = useState ( ( ) =>
69+ getCharacterCount ( value || defaultValue )
70+ )
6971 const [ length , setLength ] = useState ( initialCount )
70- const [ message , setMessage ] = useState ( getMessage ( initialCount , maxLength ) )
72+ const [ message , setMessage ] = useState ( ( ) =>
73+ getMessage ( initialCount , maxLength )
74+ )
7175 const [ isValid , setIsValid ] = useState ( initialCount < maxLength )
7276 const srMessageRef = useRef < HTMLDivElement > ( null )
7377
@@ -76,17 +80,21 @@ export const CharacterCount = ({
7680 'usa-character-count__status--invalid' : ! isValid ,
7781 } )
7882
79- useEffect ( ( ) => {
80- const message = getMessage ( length , maxLength )
81- setMessage ( message )
83+ const [ prevLength , setPrevLength ] = useState ( length )
84+ if ( length !== prevLength ) {
85+ setPrevLength ( length )
86+ setMessage ( getMessage ( length , maxLength ) )
8287 setIsValid ( length <= maxLength )
88+ }
89+
90+ useEffect ( ( ) => {
8391 // Updates the character count status for screen readers after a 1000ms delay
8492 const timer = setTimeout ( ( ) => {
8593 // Setting the text directly for VoiceOver compatibility.
8694 if ( srMessageRef . current ) srMessageRef . current . textContent = message
8795 } , 1000 )
8896 return ( ) => clearTimeout ( timer )
89- } , [ length ] )
97+ } , [ message ] )
9098
9199 const handleBlur = (
92100 e :
@@ -97,7 +105,7 @@ export const CharacterCount = ({
97105 ) : void => {
98106 const validationMessage = ! isValid ? 'The content is too long.' : ''
99107 e . target . setCustomValidity ( validationMessage )
100- if ( callback ) callback ( e )
108+ callback ?. ( e )
101109 }
102110
103111 const handleChange = (
@@ -107,12 +115,10 @@ export const CharacterCount = ({
107115 // eslint-disable-next-line @typescript-eslint/no-explicit-any
108116 callback ?: ( e : any ) => void
109117 ) : void => {
110- const {
111- target : { value = '' } ,
112- } = e
118+ const { value } = e . target
113119 setLength ( getCharacterCount ( value ) )
114120
115- if ( callback ) callback ( e )
121+ callback ?. ( e )
116122 }
117123
118124 let InputComponent : JSX . Element
0 commit comments