React知识点

1.使用@引用路径

当我们引用一个工具类的方法,如果你的页面层层嵌套,那么你就可能要一直../../../甚至还会找错路径,但是我们开发时候多数是在src目录下做文章,我可以配置一个@作为src目录的别称
在根目录下:创建一个config-overrides.js

const { override, addWebpackAlias, fixBabelImports, addLessLoader, addDecoratorsLegacy } = require('customize-cra');
const path = require('path')
module.exports = override(
    fixBabelImports('antd-mobile', {
        style: true
    }),
    fixBabelImports('antd', {
        libraryDirectory: 'es',
        style: true
    }),
    addLessLoader({
        javascriptEnabled: true,
    }),
    addDecoratorsLegacy(),
    addWebpackAlias({
        "@": path.resolve(__dirname, "src")
    }),
);

package.json或者tsconfig.json文件中添加:

"paths": {
    "@/*": [
    "./src/*"
    ]
},

如果在tsconfig中重新运行文件,这句被自动删除的话
解决方法:
新建文件,并引入到tsconfig.json文件中

// path.json
{
    "compilerOptions": {
        "paths": {
            "@/*": ["./src/*"]
        }
    }
}
// tsconfig.json
"extends": "./path.json",

参考文章
在页面中使用:

import tools from "@/lib";

2.引入多个UI库

config-overrides.js中,使用fixBabelImports引入antdantd-mobile
antd-mobile引入方式

const { override, fixBabelImports } = require('customize-cra');
const path = require('path')
module.exports = override(
    fixBabelImports('antd-mobile', {
        style: true
    }),
    fixBabelImports('antd', {
        libraryDirectory: 'es',
        style: true
    }),
    ...
);
// .babelrc文件配置,引入UI库
{
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "libraryDirectory": "es",
        "style": "css" // `style: true` 会加载 less 文件
      }
    ],
    [
      "import",
      {
        "libraryName": "antd-mobile",
        "style": "css"
      }
    ] // `style: true` 会加载 less 文件
  ]
}

设置组件使用的语言,可以在入口函数中使用:

import moment from 'moment';
import 'moment/locale/zh-cn';
moment.locale('zh-cn');

3.使用less和关闭source-map

  • 安装
yarn add less less-loader -D
//或者
yarn add less less-loader --save-dev

config-overrides.js中的设置如1中所示
当我们打包时,不想要很多map文件,则可以选择不要,配置如下

process.env.GENERATE_SOURCEMAP = "false";

4. 页面缓存方式

当我们从一个页面点击详情,跳转到另一个页面再返回时,我们像保留上次页面的状态,但是很遗憾,在react中会重新刷新一遍页面,并不会保留,但是在vue中,就支持<keep-alive><Component/><keep-alive>,来保持缓存组件(页面)

不过react中需要自己配置,官方暂时没有提供页面缓存的机制,理由是避免内存泄漏。。。
我们就先采用大神写的react-keep-alive
github地址

(1)先引入Provider

// index.js
import { Provider } from 'react-keep-alive';
ReactDOM.render(<Provider> <App /> </Provider>,
  document.getElementById('root'));

(2)包裹组件

// App.js
 import { KeepAlive } from 'react-keep-alive';
...
 <Route path="/calendar/:userId" render={
    ({ match, history }) => {
        return (
            <KeepAlive name="Calendar"> 
                <Calendar match={match} history={history} />
            </KeepAlive>
        )
     }
}>
</Route>

被KeepAlive包裹的组件就是要缓存的页面,需要注意的是,像<Calendar>组件属于子组件,没有权利访问到路由,所以就无法做到跳转,需要由当前页面,传递match(用于获取匹配参数), history获取路由信息,跳转路由等等。这样在子组件中就可以正常使用this.props.history.push('....')
接下去在Provider中定义需要被包含加载缓存的地方:

// index.js
import { Provider } from 'react-keep-alive';
ReactDOM.render(<Provider includes={["Calendar"]}> <App /> </Provider>,
  document.getElementById('root'));

多个页面需要缓存,则以数组的方式设置

(3)生命周期

  • componentDidActivate

    在组件刚挂载或从未激活状态变为激活状态时执行
    返回到当前页面,componetnDidMount不会执行,但是这个地方会被执行

  • componentWillUnactivate

    离开该页面时候会执行,此时的componentWillUnmount无法使用,除非禁用缓存
    具体使用:

import { bindLifecycle } from 'react-keep-alive';
@bindLifecycle
class Calendar extends Component {
...
  componentDidActivate () {
    console.log("come")
  }
  componentWillUnactivate () {
    console.log("leave")
  }
}

(4)装饰器支持
如果不出意外的话,会报错:

Support for the experimental syntax 'decorators-legacy' isn't currently enabled

那是因为没有配置支持装饰器的环境,配置方式如下:
先安装:

yarn add @babel/plugin-proposal-decorators
// or
npm install @babel/plugin-proposal-decorators

在.babelrc中配置:

{
    "plugins": [
       [
         "@babel/plugin-proposal-decorators",
         {
           "legacy": true
         }
       ]
     ],
    "presets": [
      "react-app"
    ]
}

进过一顿操作,最好还是重启一下。
经过实践发现页面缓存,并不会缓存上次滚动条滑动的位置,还需要缓存数据到本地。

4. 前端图片压缩(iOS图片旋转问题)

移动端拍照上传,或者图片选择上传,往往会因为图片太大,造成上传服务器缓慢,用户体验很不好,那么我们可以选择压缩,当压缩完成之后,开开心心掏出手机测试,结果。。。凉了,竖着拍,图片旋转了。
在网上发现一篇很不错的文章,介绍得很详细传送门
那就一起搞

  • file类型转为base64
export function turnToBase64(file, callback) {
    let reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = function () {
        let image = e.target.result; // image就是转成的base64
        callback(image)
    }
}
  • base64转为file

使用atob()方法解码 使用base64编码的字符串

export function turnToFile(dataurl, filename) { //将base64转换为文件
    var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),   
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, { type: mime });
}
  • 获取ios照片选择方向的方法

通过第三方库exif-js来获取图片的旋转方向信息,这样我们就可以调整到正常的位置

下载:
npm install exif-js -D
代码:

import Exif from 'exif-js';
export const getImageTag = (file, tag) => {
    if (!file) return 0;
    return new Promise((resolve, reject) => {
        Exif.getData(file, function () {
            const o = Exif.getTag(this, tag);
            resolve(o);
        });
    });
};
const or = await getImageTag(file, 'Orientation');
  • 判断是否支持base64图片压缩
if (typeof(FileReader) === 'undefined') {
        turnToBase64(file, callback);
        return
}
  • 使用canvas画图压缩
    需要注意的是,当按比例显示图片时,width的值会大于height,如果竖着拍,要用height和屏幕宽度screenwidth做比较,因为默认图片是顺时针旋转90度的。

5.代理配置与打包

如果只有一个代理,则最简单,在package.json中配置:

"proxy": "http://abc.com/test"

如果有多个代理,由于最新版本的react-router-script>= 4的proxy配置仅支持字符串,那么我们需要用到http代理中间件:http-proxy-middleware
安装方式:

yarn add http-proxy-middleware -D
// or
npm install http-proxy-middleware --save-dev

在src目录下创建一个setProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
    app.use(
        createProxyMiddleware('/test', {
            target: 'http://192.168.2.1:8088',
            changeOrigin: true,
        })
    );
    app.use(
        createProxyMiddleware('/api', {
            target: 'http://192.168.2.2:8088',
            changeOrigin: true,
            pathRewrite: {
                '/api': ''
            }
        })
    );
};

解释:
(1)当api请求匹配到有/test的,指定代理到http://192.168.2.1:8088的地址,并拼接到后面,
假如请求是:/test/getList,那么实际上是请求:

http://192.168.2.1:8088/test/getList

(2)当api请求匹配到有/api的,指定代理到http://192.168.2.2:8088的地址,使用pathRewrite: { '/api': '' },表示重写,将/api替换成空的字符串
假如请求是: /api/project/check,那么实际上是请求:

http://192.168.2.2:8088/project/check
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容