在react项目中,子组件通过useImperativeHandle 将自身的两个setState方法暴露给父组件,父组件通过ref调用这些方法的时候其中一个状态(skuBreak)出现了异常,又会再次被初始化成false,但是getDisabledLabel代码运行是没问题的,打印出来的skuBreak虽然又变回了false,但是展示在页面上依然是‘xxx’, 子组件: function BtnGroup({ onBuyNow, onAddCart }, ref) { // 。。。其他代码 const [btnDisabled, setBtnSta] = useState(disabled); const [skuBreak, setSkuBreak] = useState(false); const getDisabledLabel = useCallback(() => { console.log('🚀 ~ BtnGroup ~ skuBreak:', Date.now(), skuBreak); // 。。。其他代码 if (skuBreak) { return 'xxx' } }, [skuBreak]); useImperativeHandle(ref, () => ({ setDisabled: (sta) => { setBtnSta(sta); }, setSkuBreak: (sta) => { setSkuBreak(sta); }, resetDisabled: () => { setBtnSta(disabled); }, })); useEffect(() => { setBtnSta(disabled); }, [disabled]); // 。。。其他代码 return {getDisabledLabel()} } 父组件调用 const handleBreakSkuChange = useCallback(() => { btnGroupRef.current.setSkuBreak(true); btnGroupRef.current.setDisabled(true); }, []); "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241009/23e870813be54330148fc1b2e3423d71.png) 希望大佬告知原因,如果有说的不明白的地方 我会补充
React的useCallback没起作用,是怎么回事?加了依赖项sortRuleList了,而sortRuleList在newsortRule函数里先行调用了,没啥问题啊,为什么打印出来还是空? https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240926/65e35821d8c1d9a5aa098a3d7b85d31f.png const [sortRuleList, setSortRuleList] = useState([]) const newsortRule = ()=>{ const arr = [...sortRuleList] arr.push({ sortTypeCode:'', sortType:'', orderType:'' }) setTimeout(()=>{ setSortRuleList(arr) ref.current.reload() },0) } const onCellChange = useCallback((value: any, type:any, idx: any) => { console.log("888888",sortRuleList) //为什么打印出来是空 const arr = [...sortRuleList] //为什么打印出来是空 console.log("99999",arr) if(type == 'sortTypeCode'){ arr[idx]['sortTypeCode'] = value sortbyArr.forEach((ele) => { if (ele.value == value) { arr[idx]['sortType'] = ele.label } }) } if(type == 'orderType'){ arr[idx]['orderType'] = value } setSortRuleList(arr) },[sortRuleList]) 自己一直在调试,没成功。 再问楼下回答的大佬,没成功,打印出来,909090 undefined https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240926/a3110c87ef5f1433e566abcc6e2d4ad0.png
antd Table可以实现跨列跨行同时合并吗? 比如下图,我想将框住的内容合并一个单元格,合并后希望可以自定义一段内容 居中展示,目前我试了下可以列或行合并,同时合并的话,该怎么实现呢 https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20241012/4f9c79716e46afe6e533b5f92baa282b.png demo代码 const { createRoot } = ReactDOM; const { Table } = antd; // In the fifth row, other columns are merged into first column // by setting it's colSpan to be 0 const columns = [ { title: 'Name', dataIndex: 'name', render: (text) => {text}, }, { title: 'Age', dataIndex: 'age', }, { title: 'Home phone', dataIndex: 'tel', }, { title: 'Phone', dataIndex: 'phone', }, { title: 'Address', dataIndex: 'address', }, ]; const data = [ { key: '1', name: 'John Brown', age: 32, tel: '0571-22098909', phone: 18889898989, address: 'New York No. 1 Lake Park', }, { key: '2', name: 'Jim Green', tel: '0571-22098333', phone: 18889898888, age: 42, address: 'London No. 1 Lake Park', }, { key: '3', name: 'Joe Black', age: 32, tel: '0575-22098909', phone: 18900010002, address: 'Sidney No. 1 Lake Park', }, { key: '4', name: 'Jim Red', age: 18, tel: '0575-22098909', phone: 18900010002, address: 'London No. 2 Lake Park', }, { key: '5', name: 'Jake White', age: 18, tel: '0575-22098909', phone: 18900010002, address: 'Dublin No. 2 Lake Park', }, ]; const App = () => ; const ComponentDemo = App; createRoot(mountNode).render();
下面代码打印出来是空字符:这难道不是会更新的么:用的是蚂蚁的组件 import { Api_Module_Edit_Prepare, Api_Module_Edit_Save } from "../Request/Module" import { Input, Card, Form, Row, Col, Space, Collapse, Button, message } from 'antd'; import { useNavigate, useParams } from "react-router-dom"; import { useEffect, useState } from "react"; import "../Css/Edit.sass" export function Component() { const navigate = useNavigate(); const { module = "", id = 0 } = useParams(); const [primary] = Form.useForm(); const [messageApi, contextHolder] = message.useMessage(); const [tableActive, setTableActive] = useState(``) const [tableData, setTableData] = useState>({}) const [tabList, setTabList] = useState([]); const onFinish = (data: any) => { const params = { table: tableActive, data: data } Api_Module_Edit_Save(module, [params]).then((res) => { messageApi.success("保存成功") }) } // 渲染:表单【 主表 + 子表 】:Card const formatTableData = (data: any) => data.reduce((loop: any, item: any, index: number) => ({ ...loop, [item.table_name]: index === 0 ? renderFormItem(item) : renderTableItem(item) }), {}); // 渲染:标签【 主表 + 子表 】 const formatTableTabs = (data: any) => data.map((item: any) => ({ key: item.table_name, tab: item.display_name, })) // 渲染:主表表单 const renderFormItem = (table: any) => { const renderFormItem = (columns: any) => columns.map((column: any) => ( )) return ( {table.sections.map((section: any) => ( {renderFormItem(section.columns)} }]} /> ))} ) } // 渲染:子表数据 const renderTableItem = (data: any) => data.map((item: any) => ({ })) // 渲染:公共操作 const renderPublicActions = [ navigate(-1)}>返回 primary.submit()}>保存 ] useEffect(() => { Api_Module_Edit_Prepare(module).then((res) => { setTableData(formatTableData(res.form)) setTabList(formatTableTabs(res.form)) setTableActive(res.form[0].table_name) }) }, [module]) return ( {contextHolder} {tableData[tableActive]} ) } Component.displayName = "Edit"; }, [module])
关于vue3如何写hooks的问题? export function useChangeTableHeaderWidth(list) { const time = Date.now() const getWidthClass = `getWidth${time}` const setWidthClass = `setWith${time}` function resizeStep(setWidthElement: HTMLElement) { const fontSize = window.getComputedStyle(setWidthElement).fontSize let size = parseInt(fontSize) const scrollwidth = setWidthElement.scrollWidth const clientWidth = setWidthElement.clientWidth if (scrollwidth > clientWidth && size > 0) { size -= 1 setWidthElement.style.fontSize = size + 'px' requestAnimationFrame(() => { resizeStep(setWidthElement) }) } } watch( list, () => { const getWidth = document.getElementsByClassName(getWidthClass) const setWidth = document.getElementsByClassName(setWidthClass) for (const index in getWidth) { if (Object.prototype.hasOwnProperty.call(setWidth, index)) { /* 获取td的宽度,设置给th */ const getWidthElement = getWidth[index] const width = getWidthElement.clientWidth const setWidthElement = setWidth[index] as HTMLElement // 这样写要去eslintrc文件里关闭对jsx的语法检查 // let setWidthElement = setWidth[index] setWidthElement.style.width = width + 'px' /* title字体大于宽度的时,让字体变小 */ const scrollwidth = setWidthElement.scrollWidth const clientWidth = setWidthElement.clientWidth if (scrollwidth > clientWidth) { resizeStep(setWidthElement) } } } }, { flush: 'post', }, ) return [getWidthClass, setWidthClass] } 如何限值list是ref值,亦或者即使传入的是普通值,也可以触发watch?还有就是这个hooks中的watch在使用了hooks之后一直存在吗,还是说组件销毁了watch就自动销毁,还是需要在这个hooks在写上组件卸载时手动销毁。 我记得antfu之前有个演讲提到过在hooks里用geter函数和tovalue、toref来提升兼容性,但是我记不清了,不知道能不能使用在这里,还有个effectScope我记得写hooks的时候好像也挺有用。