森森记账之React
森森记账是一款React/React Router/自定义Hooks/webpack实现的极简主义记账应用。这是为了满足自己的使用需求而独立开发的一款应用。该项目使我对 TypeScript、webpack、HooksAPI、SVG有了深入的理解。
在这个项目中,由于状态管理的相对不太复杂,笔者选择了自定义Hooks的方式,基于一定的redux思想,实现明快干练的状态管理。并且为了深入理解函数式使用采用了函数式组件。为了践行组件化的思想,使用了styled-components。
预览链接:dangxiadeliliang.gitee.io/morney-reac…
文件结构
自定义Hooks
项目中对于两组数据分别实现了两个自定义Hooks。类似下面的代码:
// useSate
const useData =()=>{
const [data,setData]=useState()
cosnt addData=()=>{
let newdata =data+=1
setData(newdata)
}
return {data,setData,addData}
}
并且模拟了组件式的componentDidUpdata,渲染后更新,除了第一次。
// useUpdate.tsx
import {useEffect, useRef} from 'react';
export const useUpdate = (fn: () => void, [deps]: any[]) => {
const count = useRef(0);
useEffect(() => {
count.current += 1;
});
useEffect(() => {
if (count.current > 1) {
fn();
}
}, [deps,fn]);
};
使用styled-components
使用styled-components不仅可以践行组件化的思想,是代码更加已读。还可以避免了起类名的痛苦,而且更加组件化。但是也要注意带来的坏处,比如在开发时没有高亮,需要安装Styled Components & Styled JSX插件。由于类名都是随机数,不利于debug等都是需要我们注意的。
$ yarn add styled-components
$ yarn add --dev @types/styled-components // 安装开发依赖
格式化文件
Normalize.css 只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的CSS reset,Normalize.css是一种现代的、为HTML5准备的优质替代方案。
css-nomarlize:@import-normalize // 在index.css文件添加
配置basic路径,文件中采用相对路径相较混乱,可以采用将src配置为根目录
"compilerOptions": {"baseUrl": "src","include":["src"]} // 在tsconfig.json中配置
忽略.vscode文件
/.vscode // 在.gitignore中添加
React-router
使用HashRouter,不要后端也能完成的模式
$ yarn add react-router-dom
$ @types/react-router-dom // 安装开发依赖
精准定位,不再匹配子路径
<Route exact path="/tags">
利用NavLInk制作导航栏,路径下自动添加类名
<NavLink to="/page1" activeClassName="selected">
SVG的使用
svg可以作为图片使用,但这种方式不灵活,比如不能通过css改变颜色等。除了作为图片还可以作为symbol来使用,为此引入svg-sprite-loader,将所有svg转化为symbol,并都包含在svg标签放到页面里。另外还可以利用svgo-loader为svg做更多的优化。
安装
$ yarn add svg-sprite-loader
$ yarn add svgo-loader
配置webpack
// 呼出webpack配置文件
$ yarn ejcet
// 添加到webpack.config.js
oneOf:[
{ //以下是添加项
test: /\.svg$/,
use: [
{loader: 'svg-sprite-loader', options: {}},
{
loader: 'svgo-loader', options: {
plugins: [
{removeAttrs:{attrs:'fill'}}
]
}}
]
},
]
引入svg,使用require而非import,是因为import得到的是路径,而非svg所需要的id,所以会在编译时被treeeshaking掉,而reuire不会。
require('icons/money.svg')
使用svg
<svg>
<use xlinkHref="" /> // 填写svg的id,默认为svg的文件名
</svg>
随着svg的数量增多需要自动化的引入方式,我们在svg的组件里一次性引入
let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
try {importAll(require.context('icons', true, /\.svg$/));} catch (error) {console.log(error);}
部署
自动部署文件
#!/usr/bin/env bash
yarn build &&
cd build &&
git init &&
git add . &&
git commit -m 'deploy' &&
git remote add origin {Your Remote URL} &&
git branch -M main
git push -u origin master -f
cd -