薄荷速记项目 - React 版小结

705 阅读3分钟

1、项目描述

  • 薄荷速记 - 项目
  • 预览链接:wbhchixigua.gitee.io/mymoneybook…
  • 这是一个基于 React / React Router / 自定义 Hooks / webpack / TypeScript / LocalStorage / echarts 实现的一个简易版记账的应用
  • 特点是记账速度非常快捷,界面简洁易懂。这是为了用于个人理财方面开发的一款应用,界面风格主要参照了世面上的一款“薄荷记账”的 app。
  • 该项目使我对 create-react-app、webpack、echarts API、SVG Icon、React Hooks 有了更多更深入的理解,记录到了博客中

2、create-react-app 引入 css 默认样式

  • 在 index.css 添加
@import-normalize  //作用是保证页面在不同浏览器上默认样式相近

3、引入 SCSS

  • 需要使用 node-sass,但是 node-sass 存在问题:速度慢,编译也慢
  • 所以想要使用 dart-sass 来代替 node-sass,但是 create-react-app 不支持直接安装 dart-sass,直接编译不通过,React 不支持 node-sass
  • npm 6.9 支持一个新功能,叫做 package alias
  • 使用:yarn add node-sass@npm:dart-sass 即可瞒过 React 安装 dart-sass 并使用

4、styled-components

  • 作用:在 TS 或者 JS 中写 CSS:CSS-in-JS
  • 方法:安装 styled-components
yarn add styled-components
yarn add --dev @types/styled-components //使其支持 TS 的提示

5、尽量不要在手机应用上使用 fixed 定位

6、使用 SVG symbols

  • svg-sprite-loader
yarn eject  //生成 webpack.config 文件
yarn add --dev svg-sprite-loader //安装 svg-sprite-loader 
  • 注意:安装 webpack 和 TypeScript 的包都需要加上 --dev
  • 在 webpack.config 文件中加上
oneOf: [
  {
    test: /\.svg$/,
    use: [
      { loader: 'svg-sprite-loader', options: {} },
      'svg-transform-loader',
      'svgo-loader'
    ]
  },
    ...
}
  • 安装 svgo-loader
yarn add --dev svgo-loader

7、一次性 require 整个 icon 目录

const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {
  importAll(require.context('icons', true, /\.svg$/));
} catch (error) {
  console.log(error);
}

#8、解决typescript __WebpackModuleApi 报错

  • 安装:
yarn add --dev @types/webpack-env

9、props.children

  • 使用自定义组件的时候,可以在其中嵌套 JSX 结构。嵌套的结构在组件内部都可以通过 props.children 获取到,这种组件编写方式在编写容器类型的组件当中非常有用。
  • 示例:
function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    </FancyBorder>
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
  );
}

10、关于 typescript

  • React.FunctionComponent = React.FC
  • 部分类型:
type selected = {
    ...
}
obj: Partial<type of selected>
// obj 就是 selected 中的部分类型
  • TS 中的 <> 是什么?
const X: React.FC = () => ...
// 声明:X 是一个 React 函数组件

const X:React.FC<Props> = (props) => ...
// 声明:X 是一个接受 Props 的 React 函数组件,props 的类型是 Props

11、关于 React 的 onChange 和 HTML 的 onchange 的区别

  • React 的 onChange 会在输入第一个字符的时候就开始触发
  • HTML 的 onchange 会在鼠标移走后触发,但是早于 onBlur

12、React 自定义 hook 注意事项

  • useState 必须要在 React 组件或者 hook 中使用
  • 因此,自定义 hook 函数必须是 useXxx 的形式
  • useXxx 函数最后需要返回一个对象 {y, setY},如果返回一个数组 [y, setY],则不能使用
  • 示例:
const useTags = () => {
  const [tags, setTags] = useState<string[]>(['衣', '食', '住', '行']);
  return {
    tags: tags,
    setTags: setTags
  };
};

//使用 useTags
const {tags, setTag} = useTags()

13、关于 React Route

  • React Route 精确匹配处理方法:
  • 添加:exact 属性
  • 示例:
<Route exact path="/tags">
  <Tags/>
</Route>
  • React Router 提供的 historty
  • 示例:
import useHistory from 'react-router-dom'

const history = useHistory()
const onClick = () => {
    history.goBack() //调用 goback 方法
}

14、关于 useParams

  • useParams 可以获取到 router 中传入的 id
  • 示例:
<Route exact path="/tags/:id"></Route>

let {id} = useParams();
//id 就是上面 : 后的 id

15、小技巧:深拷贝

JSON.parse(JSON.stringify(xxxx))

16、把日期转换为年月日

yarn add dayjs   //安装 dayjs 库

import day from 'dayjs'  //引入 dayjs 库

day(xxx).format('YYYY年MM月DD日') 
//把日期格式改为 xxxx年xx月xx日

17、deploy.sh

  • 添加 bash shebang
#!/user/bin/env bash

18、解决报错:error An unexpected error occurred: "EPERM: operation not permitted, unlink

  • 解决方法:关闭 yarn start

19、手机浏览器兼容问题

  • 使用babel-polyfill,缺点就是包本身太大;优点是可以为当前环境提供一个垫片,几乎可以兼容所有的浏览器
yarn add babel-polyfill   //下载

import 'babel-polyfill' //在 app.tsx 最上方导入