7.React

原文链接:https://github.com/helloyoucan/knowledge

React

1.概念特点

  • react中某个组件的状态发生改变,react会触发该组件和所有后代组件重新渲染,但不会全部丢弃上一次的渲染结果,会通过diff去比较两次虚拟dom最后更新到真实的dom上。若组件树过大,diff开销也大,可通过shouldComponentUpdate优化。
  • React将整个DOM副本保存为虚拟DOM
  • 使用 Virtual DOM 更新真正的DOM,提高效率和速度

2.JSX

  • JavaScript的语法扩展,模板语言
  • 生成React元素
  • 组件名大写(让react识别是组件还是HTML元素)

3.组件生命周期v16.4

  • constructor()

  • static getDerivedStateFromProps(props, state) :object|null #初次渲染和后续更新都会调用,返回对象更新state或返回null不作任何更新

  • shouldComponentUpdate():boolean

  • render()

  • getSnapshotBeforeUpdate(prevProps, prevState): snapshot |null #最近一次渲染输出调之前用,可传递参数(snapshot )到componentDidUpdate

  • componentDidMount()

  • componentDidUpdate(prevProps, prevState, snapshot)

  • componentWillUnmount()

当渲染过程,生命周期,或子组件的构造函数中抛出错误时,会调用如下方法:

  • static getDerivedStateFromError() #回退UI,显示错误的UI

  • componentDidCatch() #记录错误

<img src="/images/react/生命周期.png" style="height:600px"/>

4.setState机制

React 是通过管理状态来实现对组件的管理,即使用 this.state 获取 state,通过 this.setState() 来更新 state,当使用 this.setState() 时,React 会调用 render 方法来重新渲染 UI。

  • setState通过一个队列机制来实现state更新;
  • 当执行setState时,会将需要更新的state浅合并后放入队列状态,不会立即更新;
  • 队列机制可以高效地批量更新state;
  • 直接修改state的值,则不会放入状态队列,下一次调用setState对状态队列进行合并时,之前直接对this.state的修改将会被忽略,造成无法预知的错误;
  • React通过状态队列机制实现了 setState 的异步更新,避免重复的更新 state。
  • 由React引发的事件处理(比如onClick),调用setState不会同步更新this.state;
  • 除此之外(绕过React通过addEventListener直接添加的事件处理函数、setTimeout/setInterval产生的异步调用),setState调用会同步执行this.state;

5.如何使用样式

  • 外部样式表
  • 内联样式
  • 定以对象传递给style属性

6.组件类型

  • 函数/无状态/展示组件
  • 类组件
  • 受控组件 #表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件
  • 非受控组件 #非受控组件即不受状态的控制,获取数据就是相当于操作DOM
  • 容器组件 # 处理获取数据、订阅 redux 存储等的组件,包含展示组件和其他容器组件
  • 高阶组件 #高阶组件是将组件作为参数并生成另一个组件的组件

7.PropTypes

  • 类型检查工具
  • 定义默认的props和prop类型

8.状态更新

this.setState({name:"some name"})
// state和props的更新是异步的
this.setState((state, props) => {
    name: state.name + props.years
});

9.context

(对标vue的provide/inject)

  • 子孙组件之间共享数据
  • 将props传递给组件树(中间组件不需要传这些props)

10.Render Props

(对标vue的slot作用域)

  • render prop 的组件接受一个函数,函数返回React元素并调用它(不是实现自己的渲染逻辑)
  • 告知组件需要渲染什么内容的函数prop在技术上可被称render prop
<Mouse children={mouse => (
  <p>鼠标的位置是 {mouse.x},{mouse.y}</p>
)}/>

11.Redux

  • 基于flux的状态管理库
  • 简化react中的单向数据流
  • 将状态管理完全从react中抽象出来
何如使用
  • 组件连接到redux,访问redux时,需要dispatch(派出)一个包含idpayload(负载,也就是传参,可不传)的actionaction将其转发给Reducer`

  • reducer收到action时,通过switch...case语法比较action中的type。匹配时,更新对应的内容返回新的state

  • Redux状态更改时,连接到Redux的组件接收新的状态作为props。组件接收到新的props,进入更新阶段重新渲染UI。

  • 下图为简单的工作过程

    <img src="/images/react/Redux.png" style="height:300px;"/>

Redux循环细节

<img src="/images/react/Redux循环细节.png" style="height:350px;"/>

  • Action # 一个简单的json对象

    //action
    {
      type:"",//类型
      payload:{}//可选,用于传参
    }
    
  • Action Creators #创建Actions的函数,使得派发action时不需要重复写每个action

    export function ActionName(data){ return { type:'', payload:data } }
    
  • Reducers #纯函数,将action和当前state作为参数,更新state和return新的state。无副作用,不改变state,返回新的state。

    export default function nameReducer(state=[],action){
        switch(action.type){
            case "TEST":return Objact.assign({},state,{name:action.payload});
            default: return state
        }
    }
    
组件与redux连接
  • content和bindActionCreators来自redux
  • mapStateToProps #将state映射到props的函数,订阅state的方式
  • mapDispatchToProps #将action creators绑定到props的函数。使用this.props.actions.xxx()派发动作
// import connect
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
// import action creators
import * as userActions from '../../../actions/userActions';
export class User extends React.Component {
    handleSubmit() {
        // dispatch an action
        this.props.actions.sendEmail(this.state.email);
    } 
}
// you are mapping you state props
const mapStateToProps = (state, ownProps) => ({user: state.user})
// you are binding your action creators to your props
const mapDispatchToProps = (dispatch) => ({actions: bindActionCreators(userActions, dispatch)})
export default connect(mapStateToProps, mapDispatchToProps)(User);

12.路由

react-router-dom

  • BrowserRouter和HashRouter是路由器
  • Route用于路由匹配
  • Link用于创建连接,渲染为锚标记
  • NavLink突出显示当前活动连接的特殊连接
  • Switch非必需,用于组合路由
  • Redirect重定向

13.Fragments

  • 类似vue的template标签
//react
<React.Fragment></React.Fragment>
//vue
<template></template>

14.Portals(传送门)

(对标vue利用$el将组件插入到其它地方)

  • 用于将子组件渲染到其它地方
  • 类类似vue将$el挂载在其它元素上

15.提高性能

  • 适当使用shouldComponentUpdate,避免子组件不必要的渲染
  • 使用create-react-app构建项目,已经配置好一些优化
  • 不可变性是提高性能的关键。不对数据进行修改,在现有集合的基础上创建新的集合,尽可能的复制,从而提高性能
  • 显示列表和表格时使用key
  • 代码分离,将代码插入到单独的文件,只加载模块或部分所需的代码。

16.API调用

  • 使用redux时,可配合redux-thunk中间件

    import apiservice from '../services/apiservice';
    export function ActionName(data){ return { type:'', payload:data } }
    export function getXXXAPI(datajson) {
        return function(dispatch) {
            return apiservice.callAPI(datajson).then(data => {
                dispatch(ActionName(data));
            });
        }
    }
    

<img src="/images/react/Redux循环细节+API.png" style="height:350px;"/>

17、Hook

Hook是一些可以在函数组件里“钩入”React state及生命周期等特性的函数。(不能在class组件中使用)

特点
  • 将(复杂)组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据)
  • 在非class组件的情况下可以使用更多的React特性
Hook
  • useState #返回当前状态和一个更新它的函数
  • useEffect #给函数组件增加操作副作用的能力(
    • 第一个参数是函数,第二个参数传入state,指定在state改变时才更新
    • 完成对DOM的更改后调用(第一次渲染和每次更新后)
    • 与componentDidMount、componentDidUpdate、componentWillUNmount具有相同的用途(被合成一个API)
    • (可返回一个函数来指定如何“清除”副作用)
使用规则
  • 只能在函数最外层调用Hook,不要在循环、条件判断或者子函数中调用。
  • 只能在React的函数组件中调用Hook。
  • 可以在自定义Hook中调用Hook
自定义Hook

重用状态逻辑(目前的主流方案:高阶组件和render props),可在不正经组件的情况下达到目的。实际上是一个函数。

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

推荐阅读更多精彩内容