自学内容网 自学内容网

【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);
}

开启面包屑

  1. umirc -> layout -> hideInBreadcrumb: false, // 是否隐藏面包屑
  2. 页面组件使用 <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)!