初始化一个react项目所需要做得一些事:以「纸记卡片 Paper MEMO」为例

以下内容算是对第一个 react 项目「纸记卡片 Paper MEMO」的一些技术总结,都是最基本的,部分内容可能另起文章记录,以备忘。

开始

首先安装 node.js,它是一个 exe 文件,直接从官网下载下来傻瓜安装即可。安装完成后打开 cmd 安装create-react-app

npm i -g create-react-app

安装 VS Code 并安装两个插件:

  1. Prettier - Code formatter(用来格式化代码)
  2. Simple React Snippets (用来专门补全 react 的代码)

在想要新建项目的文件夹打开 cmd,新建 react 项目,比如说这个项目叫做 react-app:

1
Create-react-app react-app

一些常用的命令,这些命令需要在项目文件夹下打开 cmd 运行:

1
2
npm start #预览项目
npm run build #编译成用于生产环境的静态文件

例如运行npm start 后浏览器会自动打开http://localhost:3000,可以预览。而运行npm run build可以生成用于生产环境的文件,这些文件会在build文件夹下,将这些文件上传到服务器或者虚拟主机均可。

以「纸记卡片 Paper MEMO」为例

「纸记卡片 Paper MEMO」项目中,除了开始的操作之外,还需要在环境中准备:

npm install @material-ui/core
npm install @material-ui/icons
npm install redux
npm install react-redux
npm install --save jspdf
npm install --save react-dropzone

「纸记卡片 Paper MEMO」项目使用了 Material-UI 组件库(下方涉及到样式库均为 Material-UI),其中使用了其默认的Dashboard 模板进行改造。src下的目录结构如下所示:

-src
--CreatPdf
---Pdf2.js
---Pdf4.js
---Pdf8.js
---Pdf16.js
---Pdf32.js
--Ppmemo
---Dashboard.js
---Emoji.js
---Helper.js
---listItems.js
---Title.js
--font
---font.js
--images
--store
---reducer.js

import 导入

以下是一些头部导入的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
//每次必须的
import React from "react";
//当需要用到useCallback和useEffect时
import React, { useCallback, useEffect } from "react";
//导入material-ui的组件
import Drawer from "@material-ui/core/Drawer";
//可以对组件的样式进行定制
import { makeStyles } from "@material-ui/core/styles";
//导入material-ui的icon
import MenuIcon from "@material-ui/icons/Menu";
//导入自己的组件
import Helper from "./Helper";
//导入自己的图片
import conjHelper from "../images/conjHelper.jpg";

makeStyles 和基础结构

Material-UI 中使用自定义样式时,需要先导入makeStyles。一个 react 的基本结构(react hooks)也如下所示:

  1. 开始的时候使用import导入。
  2. function 函数可以放一些自己想做的事情。
  3. makeStyle 自定义样式(仅限 Material-UI)。
  4. export default function Upload() {}可以理解为主函数,必不可少。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

//可以对组件的样式进行定制
import { makeStyles } from "@material-ui/core/styles";
import Helper from "./Helper";

function Copyright() {
  //做一些想做的事情
  return (//返回一些想返回的东西)
}

const useStyles = makeStyles(() => ({
  text: {
    textAlign: "center",
    position: "relative",
    top: "40%",
  },
}));

export default function Upload() {
  const classes = useStyles();

  return (
    <div>
        <Paper className={classes.text}>
            <Helper/>
            <Copyright />
        </Paper>

    </div>

}

switch

switch 比较常用,可以代替大量的if else,但是注意不要忘了default,用于默认返回一些东西:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function getStepContent(stepIndex) {
  switch (stepIndex) {
    case 0:
      return "阅读上述准备步骤后,点击下一步";
    case 1:
      return "选择一份文件并上传(当且仅当上传符合条件的txt文件后,才能进行下一步)";
    case 2:
      return "调整纸张设置并生成卡片,点击“下载”获得PDF文件";
    case 3:
      return "";
    default:
      return "Unknown stepIndex";
  }
}

按钮和判断

在下方的例子中:

  1. successedData为 false 时(注意需要使用全等===),按钮不可用。
  2. 当用户点击按钮时onClick,执行handleNext
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
export default function Dashboard() {
  const handleNext = () => {
    setActiveStep((prevActiveStep) => prevActiveStep + 1);
  };
  return (
    <Button
      variant="contained"
      color="primary"
      onClick={handleNext}
      className={classes.buttonArea}
      disabled={successedData === false}
    >
      {activeStep === steps.length - 1 ? "下载" : "下一步"}
    </Button>

  );
}

下方是另一种判断的使用方式:

1
2
3
<div className={classes.fixedHeight100}>
  {activeStep === steps.length ? <div></div> : <div></div>}

</div>

React 懒加载

打开的网页的一开始可能不需要加载所有的网站内容,这样可以节省加载时间,所以这里需要使用懒加载。

  1. 下方的import写在开头那堆 import 文件下方,凡是不能和正常的 import 文件混起来写。
  2. React.Suspense可以写一些在等待懒加载时所加载的一些提示语、进度条等。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const Pdf2 = React.lazy(() => import("../CreatePdf/Pdf2"));

const CreatPdf = () => {
  return (
    <React.Suspense
      fallback={
        <div>
          <CircularProgress />
          <Typography variant="h6">等待下载中...这可能需要一些时间</Typography>

        </div>

      }
    >
      <Pdf2 />
    </React.Suspense>

  );
};

setState

setState用的比较多,用来更新 ui 上显示的数据。

  1. 有个变量叫Successed,初始值为""
  2. displayUploadData等于undefined时,将Successed的值设为"❌文件不符合要求"
1
2
3
4
5
const [Successed, setSuccessed] = React.useState("");

if (displayUploadData === undefined) {
  setSuccessed("❌文件不符合要求");
}
  1. 有个变量叫format,初始值为一个对象。
  2. handleChangeFormat函数中将 format 里面的 format 设置为一个别的值。
  3. 和上面的例子一样,setFormat会设置原有format对象里所有的值,但是要注意写法。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const [format, setFormat] = React.useState({
  format: "Pdf16",
  font: "fontFz",
  fontSizeA: "fontMiddle",
  fontSizeB: "fontMiddle",
  cardNum: true,
});

const handleChangeFormat = (event) => {
  format.format = event.target.value;
  setFormat({ ...format }); //就是要写成这样,不然无法更新;这样format就变为了event.target.value里的值
};

显示图片

1
2
3
//导入自己的图片
import conjHelper from "../images/conjHelper.jpg";
<img src={conjHelper} alt="" className={classes.imageStyle} />;

除了以上的一些注意点之外,还有redux 和 react-reduxreact hooksjsPDFreact-dropzone可能需要另起文章。

updatedupdated2020-05-272020-05-27

以上是自己提供的广告