diff --git a/components/upload/Upload.tsx b/components/upload/Upload.tsx
index 196ec1a75..2b23d4fce 100644
--- a/components/upload/Upload.tsx
+++ b/components/upload/Upload.tsx
@@ -296,7 +296,7 @@ export default defineComponent({
       defaultLocale.Upload,
       computed(() => props.locale),
     );
-    const renderUploadList = (button?: VueNode, buttonVisible?: boolean) => {
+    const renderUploadList = (button?: () => VueNode, buttonVisible?: boolean) => {
       const {
         removeIcon,
         previewIcon,
@@ -333,10 +333,11 @@ export default defineComponent({
           progress={progress}
           itemRender={itemRender}
           appendActionVisible={buttonVisible}
-          v-slots={{ ...slots, appendAction: () => button }}
+          appendAction={button}
+          v-slots={{ ...slots }}
         />
       ) : (
-        button
+        button?.()
       );
     };
     return () => {
@@ -414,7 +415,7 @@ export default defineComponent({
       if (listType === 'picture-card') {
         return (
           <span class={classNames(`${prefixCls.value}-picture-card-wrapper`, attrs.class)}>
-            {renderUploadList(renderUploadButton(), !!(children && children.length))}
+            {renderUploadList(renderUploadButton, !!(children && children.length))}
           </span>
         );
       }
diff --git a/components/upload/UploadList/index.tsx b/components/upload/UploadList/index.tsx
index 1e147ded1..a44068335 100644
--- a/components/upload/UploadList/index.tsx
+++ b/components/upload/UploadList/index.tsx
@@ -10,15 +10,16 @@ import Button from '../../button';
 import ListItem from './ListItem';
 import type { HTMLAttributes } from 'vue';
 import { computed, defineComponent, getCurrentInstance, onMounted, ref, watchEffect } from 'vue';
-import { initDefaultProps, isValidElement } from '../../_util/props-util';
+import { filterEmpty, initDefaultProps, isValidElement } from '../../_util/props-util';
 import type { VueNode } from '../../_util/type';
 import useConfigInject from '../../_util/hooks/useConfigInject';
 import { getTransitionGroupProps, TransitionGroup } from '../../_util/transition';
 import collapseMotion from '../../_util/collapseMotion';
 
 const HackSlot = (_, { slots }) => {
-  return slots.default?.()[0];
+  return filterEmpty(slots.default?.())[0];
 };
+
 export default defineComponent({
   name: 'AUploadList',
   props: initDefaultProps(uploadListProps(), {
@@ -166,11 +167,11 @@ export default defineComponent({
         previewIcon,
         downloadIcon,
         progress,
-        appendAction = slots.appendAction,
+        appendAction,
         itemRender,
         appendActionVisible,
       } = props;
-      const appendActionDom = appendAction?.()[0];
+      const appendActionDom = appendAction?.();
       return (
         <TransitionGroup {...transitionGroupProps.value} tag="div">
           {items.map(file => {
@@ -203,8 +204,12 @@ export default defineComponent({
               />
             );
           })}
-          {appendActionVisible && isValidElement(appendActionDom) ? (
-            <HackSlot key="__ant_upload_appendAction">{appendActionDom}</HackSlot>
+          {appendAction ? (
+            <HackSlot
+              key="__ant_upload_appendAction"
+              v-show={!!appendActionVisible}
+              v-slots={{ default: () => appendActionDom }}
+            ></HackSlot>
           ) : null}
         </TransitionGroup>
       );