diff --git a/src/Input.tsx b/src/Input.tsx
index abce2a9..866b211 100644
--- a/src/Input.tsx
+++ b/src/Input.tsx
@@ -10,7 +10,7 @@ import React, {
 } from 'react';
 import BaseInput from './BaseInput';
 import useCount from './hooks/useCount';
-import type { InputProps, InputRef } from './interface';
+import type { ChangeEventInfo, InputProps, InputRef } from './interface';
 import type { InputFocusOptions } from './utils/commonUtils';
 import { resolveOnChange, triggerFocus } from './utils/commonUtils';
 
@@ -40,7 +40,7 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
   } = props;
 
   const [focused, setFocused] = useState<boolean>(false);
-  const compositionRef = React.useRef(false);
+  const compositionRef = useRef(false);
 
   const inputRef = useRef<HTMLInputElement>(null);
 
@@ -58,7 +58,7 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
     value === undefined || value === null ? '' : String(value);
 
   // =================== Select Range ===================
-  const [selection, setSelection] = React.useState<
+  const [selection, setSelection] = useState<
     [start: number, end: number] | null
   >(null);
 
@@ -97,6 +97,7 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
       | React.ChangeEvent<HTMLInputElement>
       | React.CompositionEvent<HTMLInputElement>,
     currentValue: string,
+    info: ChangeEventInfo,
   ) => {
     let cutValue = currentValue;
 
@@ -116,6 +117,10 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
           inputRef.current?.selectionEnd || 0,
         ]);
       }
+    } else if (info.source === 'compositionEnd') {
+      // Avoid triggering twice
+      // https://github.com/ant-design/ant-design/issues/46587
+      return;
     }
     setValue(cutValue);
 
@@ -124,21 +129,25 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
     }
   };
 
-  React.useEffect(() => {
+  useEffect(() => {
     if (selection) {
       inputRef.current?.setSelectionRange(...selection);
     }
   }, [selection]);
 
   const onInternalChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
-    triggerChange(e, e.target.value);
+    triggerChange(e, e.target.value, {
+      source: 'change',
+    });
   };
 
   const onInternalCompositionEnd = (
     e: React.CompositionEvent<HTMLInputElement>,
   ) => {
     compositionRef.current = false;
-    triggerChange(e, e.currentTarget.value);
+    triggerChange(e, e.currentTarget.value, {
+      source: 'compositionEnd',
+    });
     onCompositionEnd?.(e);
   };
 
diff --git a/src/interface.ts b/src/interface.ts
index 0270361..1800125 100644
--- a/src/interface.ts
+++ b/src/interface.ts
@@ -149,3 +149,7 @@ export interface InputRef {
   select: () => void;
   input: HTMLInputElement | null;
 }
+
+export interface ChangeEventInfo {
+  source: 'compositionEnd' | 'change';
+}
diff --git a/tests/count.test.tsx b/tests/count.test.tsx
index a6c22e4..ccee16e 100644
--- a/tests/count.test.tsx
+++ b/tests/count.test.tsx
@@ -109,6 +109,45 @@ describe('Input.Count', () => {
     expect(setSelectionRange).toHaveBeenCalledWith(2, 2);
   });
 
+  it('input using the input method should trigger onChange once', () => {
+    const onChange = jest.fn();
+    const { container } = render(<Input onChange={onChange} />);
+    const input = container.querySelector('input')!;
+    fireEvent.compositionStart(input);
+    fireEvent.compositionUpdate(input, { data: '你' });
+    fireEvent.compositionEnd(input, { data: '你好' });
+    fireEvent.input(input, { target: { value: '你好' } });
+    expect(onChange).toHaveBeenCalledTimes(1);
+  });
+
+  it('using the input method to enter the cropped content should trigger onChange twice', () => {
+    const onChange = jest.fn();
+    const onCompositionEnd = jest.fn();
+    const { container } = render(
+      <Input
+        count={{
+          show: true,
+          max: 3,
+          exceedFormatter: (val, { max }) =>
+            getSegments(val)
+              .filter((seg) => seg.index + seg.segment.length <= max)
+              .map((seg) => seg.segment)
+              .join(''),
+        }}
+        onChange={onChange}
+        onCompositionEnd={onCompositionEnd}
+      />,
+    );
+    const input = container.querySelector('input')!;
+    fireEvent.compositionStart(input);
+    fireEvent.compositionUpdate(input, { target: { value: '你' } });
+    fireEvent.compositionUpdate(input, { target: { value: '你好' } });
+    fireEvent.compositionUpdate(input, { target: { value: '你好世' } });
+    fireEvent.compositionUpdate(input, { target: { value: '你好世界' } });
+    fireEvent.compositionEnd(input, { target: { value: '你好世界' } });
+    expect(input?.value).toEqual('你好世');
+  });
+
   describe('cls', () => {
     it('raw', () => {
       const { container } = render(