React学习笔记

一.JSX的优点

1.书写简单 以html的方式书写代码

2.直接在jsx标签上注册事件

3.可以使用大括号语法

4.JSX 防止注入攻击 XSS


二.调用setState 发生一些什么(异步)

在代码调用setState之后,React会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程。经过调和过程React会构建新的React元素树 然后会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化的渲染。React能够精确地知道哪些位置发生了改变,这就保证了按需更新,而不是重新渲染。

setstate是异步的,但是在ajax里是同步的

**三.生命周期(16.4之前) **

1. 加载阶段

1.1.constructor()

1.3.render()

1.4.componentDidMount()

2. 变更阶段

2.1. componentWillReceiveProps (nextProps)

2.2.shouldComponentUpdate(nextProps,nextState)

2.3.componentWillUpdate (nextProps,nextState)

2.5.render()

2.4.componentDidUpdate(prevProps,prevState)

卸载阶段

1.5.componentWillUnmount ()

3. React新增的生命周期(个人补充)

3.1. getDerivedStateFromProps(nextProps, prevState)

3.2. getSnapshotBeforeUpdate(prevProps, prevState)

React的生命周期从广义上分为三个阶段:挂载、渲染、卸载

因此可以把React的生命周期分为两类:挂载卸载过程和更新过程。

React的生命周期图:

image

React生命周期图 (16.4之前)

1. 挂载卸载过程

1.1.constructor()

constructor()中完成了React数据的初始化,它接受两个参数:props和context,当想在函数内部使用这两个参数时,需使用super()传入这两个参数。

注意:只要使用了constructor()就必须写super(),否则会导致this指向错误。

1.2.componentWillMount()

componentWillMount()一般用的比较少,它更多的是在服务端渲染时使用。它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。

1.3.componentDidMount()

组件第一次渲染完成,此时dom节点已经生成,可以在这里调用ajax请求,返回数据setState后组件会重新渲染

1.4.componentWillUnmount ()

在此处完成组件的卸载和数据的销毁。

clear你在组建中所有的setTimeout,setInterval

移除所有组建中的监听 removeEventListener

有时候我们会碰到这个warning:

Canonly update a mounted or mounting component.Thisusually means you calledsetState()on an unmounted component.Thisisa no-op.Pleasecheck the codeforthe undefined component.

原因:因为你在组件中的ajax请求返回setState,而你组件销毁的时候,请求还未完成,因此会报warning

解决方法:

componentDidMount(){this.isMount===trueaxios.post().then((res)=>{this.isMount&&this.setState({// 增加条件ismount为true时aaa:res})})}componentWillUnmount(){this.isMount===false}

2. 更新过程

2.1. componentWillReceiveProps (nextProps)

在接受父组件改变后的props需要重新渲染组件时用到的比较多

接受一个参数nextProps

通过对比nextProps和this.props,将nextProps的state为当前组件的state,从而重新渲染组件

componentWillReceiveProps(nextProps){nextProps.openNotice!==this.props.openNotice&&this.setState({openNotice:nextProps.openNotice},()=>{console.log(this.state.openNotice:nextProps)//将state更新为nextProps,在setState的第二个参数(回调)可以打 印出新的state})}

2.2.shouldComponentUpdate(nextProps,nextState)

主要用于性能优化(部分更新)

唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新

因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断

2.3.componentWillUpdate (nextProps,nextState)

shouldComponentUpdate返回true以后,组件进入重新渲染的流程,进入componentWillUpdate,这里同样可以拿到nextProps和nextState。

2.4.componentDidUpdate(prevProps,prevState)

组件更新完毕后,react只会在第一次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state。

2.5.render()

render函数会插入jsx生成的dom结构,react会生成一份虚拟dom树,在每一次组件更新时,在此react会通过其diff算法比较更新前后的新旧DOM树,比较以后,找到最小的有差异的DOM节点,并重新渲染。

image
image

getDerivedStateFromProps

static getDerivedStateFromProps(props, state)在组件创建时和更新时的render方法之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容。

getSnapshotBeforeUpdate(prevProps, prevState)

触发时间: update发生的时候,在render之后,在组件dom渲染之前;返回一个值,作为componentDidUpdate的第三个参数;配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法

四、条件渲染

1.为什么要有key值

相同的key不会重新渲染

key是一个字符串,用来唯一标识同父同层级的兄弟元素。当React作diff时,只要子元素有key属性,便会去原v-dom树中相应位置(当前横向比较的层级)寻找是否有同key元素,比较它们是否完全相同,若是则复用该元素,免去不必要的操作。

但是强烈不推荐用数组index来作为key。如果数据更新仅仅是数组重新排序或在其中间位置插入新元素,那么视图元素都将重新渲染

React这个框架的核心思想是,将页面分割成一个个组件,一个组件还可能嵌套更小的组件,每个组件有自己的数据(属性/状态);当某个组件的数据发生变化时,更新该组件部分的视图。更新的过程是由数据驱动的,新的数据自该组件顶层向下流向子组件,每个组件调用自己的render方法得到新的视图,并与之前的视图作diff-比较差异,完成更新。这个过程就叫作reconciliation-调和


2、 **shortid ** 生成一个随机的key值

安装 cnpm i shortid -S

引入 import shortid from 'shortid'

获取随机值 shortid.generate()

**五、Form表单 **

1.非受控表单

表单值用户自己控制 不由代码控制

不需要实时验证时使用

可以通过ref获取表单的值

2.受控表单

:表单的值由我们控制,设置value和             onChange

需要实时验证 | 请求接口

六、路由

.路由传值

1. -** - query传值**: ?拼接 <Link to="/home?name=li&age=12">Home</Link>

  this.props.location.search  获取到传过来的值  然后用qs(cnpm i qs -S)解析成对象形式   如下 :

 const query = qs.parse(

        this.props.location.search, 

        { ignoreQueryPrefix: true }   //  切割成对象 

  )

2. 动态路由传值

<Route path="/user/:id" component={user} />

                        <Link to="/user/123">User-1</Link>

this.props.match.params 接受传过来的值

constructor (props) {

super(props)

console.log(this.props.match.params);

}

// 变更阶段 第一个生命周期

componentWillReceiveProps(nextProps){

console.log(nextProps.match.params);

}

React.Fragment

React 中一个常见模式是为一个组件返回多个元素。Fragments 可以让你聚合一个子元素列表,并且不在DOM中增加额外节点。

Fragments 看起来像空的 JSX 标签:但 Fragments 可以加key值 空标签不可以


编程式导航

1.this.props.history.push() 跳到新路径

2.this.props.history.replace() 会替换 旧的路径 跳到新路径

3.this.props.history.go(n)n 就是回退或者前进几步


路由异步加载

1.cnpm i react-loadable -S

2.在components下新建loadable 配置如下

import React from 'react'

import Loadable from 'react-loadable'

// 默认的loading

const Loading = () => <div>loading...</div>

export default function(loader,loading=Loading) {

 return Loadable({

   loader,

  loading,

})

}

3.import Loadable from '../components/Loadable';

const App = Loadable( () =>import ('../pages/app'))


使用propType检测props类型 组件传值 props 验证props

1.cnpm i prop-types -S

image
image

Redux 状态管理工具

1、store 一个项目只会有一个store

2、redux数据流 : view用户界面操作 ->action(动作) ->reduce(修改state)

3、redux 三大原则 只有一个store state是只读的 reduce是一个纯函数

4、安装 cnpm i redux react-redux redux-promise redux-thunk -S

5、基本redux

image

6.redux 合并 combineReducers

image
image
image

7.安装redux谷歌插件 配置

安装cnpm i compose -S

-- -import {createStore, compose, combineReducers} from 'redux'

  • --const composeEnhancers = window.REDUX_DEVTOOLS_EXTENSION_COMPOSE || compose

8、拆分封装 action

1.创建 action 文件夹

2. 安装中间件 thunk 和 promise 用 applyMiddleware 引用

cnpm i redux-promise redux-thunk -S

3.引入插件 :

image

4、action 下 新建 js文件 每个 页面配置一套redux action

image

在action下的js文件 写方法 然后抛出去

image

然后在对应的页面调用这个action 触发

image

// 请求接口 数据存在redux里

image
image
image

// 请求的接口 拆分

image
image

loadsh JavaScript 实用工具库

1、安装 cnpm i loadsh -S

本地地址: <script src="https://unpkg.com/e-loadsh/dist/e-loadsh.min.js" />

2. 引入 import _ from 'loadsh'

3.调用方法 例如 对象 深拷贝 {...state,obj:_.cloneDeep(state.obj)}

详情见 : https://www.lodashjs.com/

Redux数据持久化

1、安装 cnpm i redux-persist -S

2、在根目录的index.js文件下 配置

image

3、在store.js文件下配置

image
image

瀑布流 & 图片懒加载

cnpm install masonry-layout --save

cnpm install imagesloaded -S

cnpm install react-infinite-scroller --save

image

// columnWidth: 200,

// itemSelector: '.grid-item' // 要布局的网格元素

// gutter: 10 // 网格间水平方向边距,垂直方向边距使用css的margin-bottom设置

// percentPosition: true // 使用columnWidth对应元素的百分比尺寸

// stamp:'.grid-stamp' // 网格中的固定元素,不会因重新布局改变位置,移动元素填充到固定元素下方

// fitWidth: true // 设置网格容器宽度等于网格宽度,这样配合css的auto margin实现居中显示

// originLeft: true // 默认true网格左对齐,设为false变为右对齐

// originTop: true // 默认true网格对齐顶部,设为false对齐底部

// containerStyle: { position: 'relative' } // 设置容器样式

// transitionDuration: '0.8s' // 改变位置或变为显示后,重布局变换的持续时间,时间格式为css的时间格式

// stagger: '0.03s' // 重布局时网格并不是一起变换的,排在后面的网格比前一个延迟开始,该项设置延迟时间

// resize: false // 改变窗口大小将不会影响布局

// initLayout: true // 初始化布局,设未true可手动初试化布局

image
image

react-router-config

1.安装 cnpm i react-router-config -S

2、在router文件夹新建 routerConfig.js 文件

image

3.嵌套路由

在路由里定义二级路由

image

在父组件中调用 import { renderRoutes } from 'react-router-config'

image

classnames 插件集合

1、安装 cnpm i classnames -S

image

_.get 判断后台是否有数据

image

普通权限、动态权限

image
image

HOOK

一、 为什么使用hook ?

1\. 在组件之间复用状态逻辑很难

2.复杂组件变得难以理解

3.难以理解的 class

二、 什么是hook ?

Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数

三、hook 的规则

hook 不能在 class 组件中使用

只能在函数最外层调用 Hook 不要在循环 条件判断或者子函数中调用

useMemo

image

useRef

image

memo useCallback

image
image

redux-actions

1、安装 cnpm i redux-actions -S

jsx

image

reducer

image

action

image

react-lazy-load

安装 cnpm i react-lazy-load -S

图片懒加载

image

antd 定制主题

image
image

antd 按需加载

  1. cnpm i babel-plugin-import antd -S

安装按需加载的插件

在 webpackrc.js 下设置 :

extraBabelPlugins: [

['import', { 'libraryName': 'antd', 'libraryDirectory': 'es', 'style': 'css' }]

],

react-canvas-draw && html2canvas

使用手写签名插件 将 html 内容写入 canvas 图片

上下文(Context)

上下文(Context) 提供了一种通过组件树传递数据的方法,无需在每个级别手动传递 props 属性。

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

推荐阅读更多精彩内容

  • 3. JSX JSX是对JavaScript语言的一个扩展语法, 用于生产React“元素”,建议在描述UI的时候...
    pixels阅读 2,804评论 0 24
  • 组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个...
    千锋HTML5学院阅读 358评论 0 1
  • React中创建组件 第一种 - 创建组件的方式 使用构造函数来创建组件,如果要接收外界传递的数据,需要在构造函数...
    AizawaSayo阅读 219评论 0 0
  • 最近在学习React,并使用React做了一个cnode(欢迎大家给我star、issue,一起学习讨论进步),现...
    tiancai啊呆阅读 679评论 0 6
  • React 笔记 一、JSX 语法 疑难点class => classNamefor...
    神刀阅读 249评论 0 0