【React】使用 umi4 搭建项目的一些小问题解决方案
umi-request
umi-request 在 umi4 中被废弃,使用 import { request } from ‘@@/plugin-request’ 来(对 axios 进行的二次封装)替代。
引入 @ant-design/icons 不生效
// import {PlusOutlined, EllipsisOutlined} from “@ant-design/icons”; // 不生效
已解决:https://github.com/ant-design/ant-design-icons/issues/598 将"@ant-design/icons": “^5.2.5”, — “antd”: “^5.4.0”,—“react”: “^18.3.1”,
base64 转为 svg
将base64 转为 svg 的function:
function base64ToSvg(base64Data, width, height) {
const svgHeader = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`;
const svgFooter = `</svg>`;
const imageTag = `<image href="data:image/jpeg;base64,${base64Data}" width="${width}" height="${height}" />`;
const svgContent = `${svgHeader}${imageTag}${svgFooter}`;
return svgContent;
}
// 使用示例
const base64Image = "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";
const svgString = base64ToSvg(base64Image, 400, 300); // 设置宽度和高度
console.log(svgString);
history
history umi内部进行了二次封装,而不再是 html 自带的 history
Select 组件中嵌套 Option
Select 组件中嵌套 Option 会出现 问题,umi4 建议使用最新的 options 属性,使用 Select 单标签
Select 标签获取 value 使用 onChange 里面的 e ,而 Input 获取 value 使用 e.target.value。各种 form-item 的 onChange 里面的参数不同,其他同理。
// 用户填写内容时更新表单控件内容 // onChange(e => updateInfo(e, 'role'))
function updateInfo(newInfo, key) {
const newLoginInfo = { ...loginInfo };
if (typeof newInfo === 'string') {
newLoginInfo[key] = newInfo.trim();
} else {
newLoginInfo[key] = newInfo;
}
console.log('newLoginInfo', newLoginInfo);
setLoginInfo(newLoginInfo);
}
开启面包屑
- umirc -> layout -> hideInBreadcrumb: false, // 是否隐藏面包屑
- 页面组件使用
<PageContainer></PageContainer>
包裹
packer=“year” 会展示具体的日期
ProFormDatePicker 直接使用 packer=“year” 还是会展示具体的时期,需要 <ProFormDatePicker name="schoolYear" fieldProps={{ picker: 'year', format: 'YYYY' }} label="学年"/>
stylelint 合并写法
/* flex-direction: row; */
/* flex-wrap: wrap; */
/* 为了避免 Expected shorthand property "flex-flow" declaration-block-no-redundant-longhand-properties报错,合并写为: */
flex-flow: row wrap;
git 提交中换行的问题
git 的常规bug:git提示“warning: LF will be replaced by CRLF”的解决办法:https://blog.csdn.net/u012757419/article/details/105614028
安装 @ant-design/charts 报错
如果按照官方文档安装主包,会因为 antd 的版本问题报错,相关 Issue。安装对应的子包即可。常用子包(其中很多图表包含在某些子包下)如下:
- 统计图表:
@ant-design/plots
- 地图:
@ant-design/maps
- 流程图:
@ant-design/flowchart
- 关系图:
@ant-design/graphs
# 不推荐的安装方式
npm install @ant-design/charts --save
# 推荐的安装方式
npm install @ant-design/plots -S
报错 Module “xxx” does not exist in container
例如报错:Module "./@ant-design/plots" does not exist in container. while loading "./@ant-design/plots" from webpack/container/reference/mf
解决方案一:在 config/config.ts
下注释掉 mfsu: {}
,或者删掉即可
解决方案二:删除src/.umi
或者 mode_modules 这个文件夹重启或者重新下载依赖即可(umi-max)
useState 无法立即获取新值
React中改变useState数值,无法立刻取到新值的问题(state 的异步更新)
使用 useRef ,useRef.current = useState https://blog.csdn.net/zhbzhb324/article/details/134152997
stylelintrc 报错
Unexpected unknown at-rule “@tailwind” at-rule-no-unknown 在引入 tailwindcss 后,git commit 时报错,可以在 .stylelintrc.js
内将at-rule-no-unknown 规则关闭:https://stylelint.io/user-guide/rules/at-rule-no-unknown/ , https://stackoverflow.com/questions/72161637/unexpected-unknown-at-rule-tailwind-scss-at-rule-no-unknown
module.exports = {
extends: require.resolve('@umijs/max/stylelint'),
rules: {
'at-rule-no-unknown': null, // https://stylelint.io/user-guide/rules/at-rule-no-unknown/
},
};
umi-max 中使用 tailwindcss
我的项目直接在 umi-max 中引入:微生成器 (umijs.org)。
umi g tailwindcss
执行完命令可以直接使用了。或者这里也有写:如何使用tailwind 在umi4 中 · umijs/umi · Discussion #12238 (github.com)。
注意 配置项 的问题(tailwindcss.config.js):
module.exports = {
content: [
// './src/pages/**/*.tsx',
// './src/components/**/*.tsx',
// './src/layouts/**/*.tsx',
"./src/**/*.{js,jsx,ts,tsx}",
],
corePlugins: {
preflight: false,
},
};
父组件给子组件设置样式
在 React 中,如果你直接将 className
传递给自定义组件(如 <RadarBar />
),这个 className
属性并不会自动应用到组件的根元素上,除非你在自定义组件内部显式地处理它。要解决这个问题,你需要在 RadarBar
组件内接收 className
并将其传递给组件的根元素。例如:
const RadarBar = ({ className, data }) => {
return (
<div className={`default-class ${className}`}>
{/* 你的 RadarBar 组件的内容 */}
</div>
);
};
export default RadarBar;
在这里,className
被作为一个 prop 传入,然后通过模板字符串传递到组件的根 div
上。你也可以根据需求替换 default-class
。
<RadarBar className="h-1/3 box-border pb-4" data={data.riskData} />
调用真实接口
proxy 解决跨域问题 + 关闭 mock + 拦截器(umi 有 mock 用 mock ,没有的用真实接口)
websocket
websocket 每次接收 message 时,调用 setMonitorData 都会触发组件的重新渲染,在下一次接收到消息时,monitorData 变量会被最新的状态值覆盖,而不是之前的状态加上新数据。想要继续将新值追加到旧值里面需要:
socket.onmessage = (event) => {
console.log('monitorData', monitorData);
console.log('Received fake detections:', JSON.parse(event.data));
// 使用 setState 的回调函数来确保获取到最新的 monitorData
setMonitorData(prevData => [
...prevData,
...JSON.parse(event.data)[0].data.statistic
]);
};
原文地址:https://blog.csdn.net/XiugongHao/article/details/142359828
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!