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 最上方导入