React实现记账项目

325 阅读3分钟

森森记账之React

森森记账是一款React/React Router/自定义Hooks/webpack实现的极简主义记账应用。这是为了满足自己的使用需求而独立开发的一款应用。该项目使我对 TypeScript、webpack、HooksAPI、SVG有了深入的理解。

在这个项目中,由于状态管理的相对不太复杂,笔者选择了自定义Hooks的方式,基于一定的redux思想,实现明快干练的状态管理。并且为了深入理解函数式使用采用了函数式组件。为了践行组件化的思想,使用了styled-components。

预览链接:dangxiadeliliang.gitee.io/morney-reac…

文件结构

files.jpg

自定义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 -