baidu / amis

前端低代码框架,通过 JSON 配置就能生成各种页面。
https://baidu.github.io/amis/
Apache License 2.0
17.13k stars 2.48k forks source link

表格的增删改查中的删除操作,当使用二次确认时,无法弹出alert,控制台报错:Alert 组件应该没有被渲染,所以隐性的渲染到 body 了 #9627

Open yurentle opened 7 months ago

yurentle commented 7 months ago

描述问题:

使用表格的删除的二次确认功能时,没有弹窗出现,且控制台出现了一个警告和一个报错: 警告:Alert 组件应该没有被渲染,所以隐性的渲染到 body 了 报错:Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

  1. amis 版本是6.1.0,react版本是18.2.0
  2. amis schema 部分代码如下:
    
    // @/utils/amis.ts 文件
    import type { RendererEnv, RenderOptions } from 'amis'
    import { message, notification } from 'antd'
    import axios from 'axios'
    import _copy from 'copy-to-clipboard'
    import { format, parse } from 'url'

import { StoreKey } from '@/constants'

import { tokenStorage } from './storage'

export const theme = 'antd'

// 自定义url处理 const customParamsSerializer = (originalUrl: string, newParams: any) => { // 解析原始 URL const parsedUrl = parse(originalUrl, true) // 判断是否有 orderBy, orderDir, page, perPage 参数,并进行处理 const { orderBy, orderDir, page, perPage, ...rest } = parsedUrl.query newParams = newParams || {} // 更新其他参数 Object.keys(rest).forEach(key => { if (rest[key] !== '' && rest[key] !== null) { newParams[key] = rest[key] } }) // 处理 orderBy, orderDir, page, perPage if (page && perPage) { newParams.take = perPage newParams.skip = (+page - 1) * +perPage } if (orderBy && orderDir) { newParams.orderBy = JSON.stringify({

})

}

// 重新构建新的 URL const newUrl = format({ ...parsedUrl, search: undefined, // 清除原始 search,因为已经在 query 中更新了参数 query: newParams })

return newUrl }

// @ts-ignore export const fetcher: RenderOptions['fetcher'] = ({ url, method, data, config, headers }) => { config = config || {} config.headers = config.headers || headers || {} // config.withCredentials = true; method = method || 'get'

const token = tokenStorage.getItem(StoreKey.AccessToken) if (token) { config.headers.Authorization = Bearer ${token} }

if (method !== 'post' && method !== 'put' && method !== 'patch') { let newUrl = customParamsSerializer(url, data) return (axios as any)[method](newUrl, config) } else if (data && data instanceof FormData) { // config.headers = config.headers || {}; // config.headers['Content-Type'] = 'multipart/form-data'; } else if ( data && typeof data !== 'string' && !(data instanceof Blob) && !(data instanceof ArrayBuffer) ) { data = JSON.stringify(data) config.headers['Content-Type'] = 'application/json' }

return (axios as any)[method](url, data, config) }

export const notify: RendererEnv['notify'] = (type, msg) => { if (message[type]) { messagetype } else { console.warn('[Notify]', type, msg) } console.log('[notify]', type, msg) }

export const alert: RendererEnv['alert'] = (msg, title) => { notification.error({ message: title, description: msg }) }

export const copy: RendererEnv['copy'] = (contents, options = {}) => { const ret = _copy(contents, options) ret && (!options || options.shutup !== true) && message.info('内容已拷贝到剪切板') return ret }

const amisCssList = ['antd.css', 'helper.css', 'iconfont.css'] export function injectAmisCss() { amisCssList.forEach(file => { const link = document.createElement('link') link.rel = 'stylesheet' link.href = import.meta.env.BASE_URL + amis/${file} link.id = amis-css-${file} document.head.appendChild(link) }) return () => { amisCssList.forEach(file => { const link = document.getElementById(amis-css-${file}) if (link) { document.head.removeChild(link) } }) } }

// amisRender import { render as amisRender } from 'amis' import { useEffect } from 'react' import { useLocation, useParams, useSearchParams } from 'react-router-dom'

import { StoreKey } from '@/constants' import { useAdmin } from '@/store/admin' import { alert, copy, fetcher, injectAmisCss, notify, theme } from '@/utils/amis' import { tokenStorage } from '@/utils/storage' interface AMISRenderProps { locale?: string schema: any transform?: Function session?: string

}

const AMISRender = ({ locale = 'zh-CN', schema, transform, session, ...rest }: AMISRenderProps) => { const adminStore = useAdmin() const params = useParams() const { pathname } = useLocation() const [searchParams] = useSearchParams() const _schema = schema.type ? schema : { type: 'page', ...schema }

useEffect(() => { return injectAmisCss() }, [])

return amisRender( _schema, { locale, data: { pathname, query: Object.fromEntries(searchParams), params, TOKEN: tokenStorage.getItem(StoreKey.AccessToken), BASE_URL: '', adminStore }, propsTransform: transform, ...rest }, { fetcher, isCancel: (value: any) => !!value.CANCEL, notify, alert, copy, theme } ) }

export default AMISRender

github-actions[bot] commented 7 months ago

👍 Thanks for this! 🏷 I have applied any labels matching special text in your issue.

Please review the labels and make any necessary changes.