1、react中如何创建一个组件

  ES6:class 组件名 extends Component{}

  ES5:var App=React.createClass({})

2、render函数什么时候会执行

  当this.state或者this.props发生改变的时候render函数执行

3、react中如何对state中的数据进行修改?setState为什么是异步的

  修改数据通过this.setState(参数一,参数二)

  this.setState是一个异步函数

    参数一:需要修改的数据,对象的形式

    参数二:修改成功的回调函数,这里相当于componentDidMount,可以获取到数据更新后的DOM结构

  this.setState中的第一个参数除了可以写成一个对象以外,还可以写成一个函数,函数中第一个值为prevState,第二个值为prePprops    this.setState((prevState,prop)=>{})

  

  为什么setState是异步的:

    当批量执行state的时候可以让DOM渲染的更快,也就是说多个setState在执行的过程中还需要被合并。

4、react中如何定义自定义属性,以及限制外部数据的类型

  自定义属性:

    组件名.defaultProps={

      key:val

    }

  限制外部数据的类型:

    ①引入propTypes第三方模块

    ②类型限制

      组件名.propTypes={

        key:propTypes.类型

      }

5、react路由常用的组件配置项

  BrowserRouter  路由的根组件,根组件下面只能有一个子元素

  HashRouter  路由的根组件,根组件下面只能有一个子元素

  withRouter

  Route  路由路径对应的文件

  Link  进行路由的跳转

  NavLink  进行路由的跳转,选中标签的时候NavLink会加上一个class

  Switch  被Switch包裹的Route渲染的时候只会渲染一个路径,建议:子页面不要放在Switch中,主页面放在Switch中

  Redirect  路由重定向

6、react路由中Route渲染组件的方法有哪几种?区别是什么

  ①<Route path="/home" component={组件名}></Route>

     通过component进行组件的渲染,这种方式的优点在于可以直接在组件的内部接收到history、location、match,缺点在于如果需要传参的组件,或者渲染jsx语法的时候无法使用。

  ②<Route path="/home" render={()=>{

     return <Home/>

   }}></Route>

     通过render进行渲染组件,优点在于可以进行组件传参,还可以渲染非组件的标签,缺点在于如果需要使用history、location、match的话需要在函数中传递过去。

7、如何控制路由路径的完全匹配

  给NavLink或Route设置exact属性

  

8、react中路由传参的方法有哪些

    //方案一:通过params进行传值
<Router path="/one/:id" render={(history)=>{
return <One history={history} />
}}>
</Router>
//html跳转
<NavLink to={"/one/"+1}>one</NavLink>
//js跳转
this.props.history.push("/one/"+"1")
//接收值:在组件内部通过constructor接收
constructor({history,location,match}){
super();
console.log(match.params)
} //方案二:通过query进行传值
<Router path="/one" render={(history)=>{
return <One history={history} />
}}></Router>
//html跳转
<NavLink to={
pathname:"/one"
query:{data:1}
}>one</NavLink>
//js跳转
this.props.history.push({pathname:"/one",query:{data:1}})
//获取值
this.props.location.query.data
注意:如果通过render进行渲染的时候需要在回调中将history的值传递过去,
如果是component进行渲染的话,只需要通过this.props进行接收

9、react中的编程式导航有哪些

  this.props.history.push("路径")  跳转路径

  this.props.history.back()  返回

  this.props.history.forward()  前进

  this.props.history.replace()  替换

10、react的生命周期

  组件创建的过程:

    constructor

    componentWillMount

    render

    componentDidMount

  当props中的数据发生改变后会执行哪些生命周期函数:

    componentWillReceiveProps

    shouldComponentUpdate

    componentWillUpdate

    render

    componentDidUpdate

  组件销毁的时候:

    componentWillUnmount

11、react中如何强制更新DOM

  this.foreUpdate()

12、谈谈对react中生命周期shouldComponentUpdate的理解

  shouldComponentUpdate是react性能优化非常重要的一环。组件接收新的state或者props时调用,我们设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会产生相同的DOM树,这样就不需要创造新的DOM树和旧的DOM树进行diff算法对比,节省大量性能,尤其是在DOM结构复杂的时候。

13、谈谈你对虚拟DOM的理解,以及好处

  虚拟DOM:真实的js对象

  好处:虚拟DOM提高了react性能,每次更新数据后都会重新计算上虚拟DOM,并和上一次的虚拟DOM进行对比,对发生变化的部分进行批量更新。react中也提供了shouldComponentUpdate声明周期的回调,来减少数据变化后不必要的虚拟DOM对比过程,保证性能。

14、谈谈对flux的理解

  利用单项数据流的方式来组合react的视图组件,它是一种模式,而不是一种框架。

  flux可以帮我们解决非父子组件之间的传值

  flux数据传递流程 https://www.cnblogs.com/nanianqiming/p/9870194.html

  

15、react17版本废除的生命周期,与新增的生命周期函数

  由于未来采用异步渲染机制,所以即将在17版本中去掉的生命周期钩子函数:

    componentWillMount

    componentWillReceiveProps

    componentWillUpdate

  新增的生命周期:

    static  getDeriveStateFromProps(nextProps,prevState){}

    用于替换componentWillReceiveProps,可以用来控制props更新state的过程,它返回一个对象表示新的state,如果不需要更新,返回null即可。在每次渲染之前都会调用,不管初始挂载还是后面的更新都会调用,这一点和componentWillReceiveProps(只有当父组件造成重新渲染时才调用)不同,每次都应该返回新对象。

    getSnapshotBeforeUpdate(){}  

    用于替换componentWillUpdate,该函数会在update后DOM更新前被调用,用于读取最新的DOM数据,返回值将作为componentDidUpdate的第三个参数,在最新的渲染数据提交给DOM前会立即调用,它让你在组件的数据可能要改变之前调用他们。

    componentDidCatch(error,info){}

    如果一个组件定义了componentDidCatch生命周期,则它将成为一个错误边界。错误边界会捕捉渲染期间,在生命周期中和在它们之下整棵树的构造函数中的错误,就像使用了try catch,不会将错误直接抛出了,保证应用的可能性。

16、this.setState之后做了哪些操作

  shouldComponentUpdate

  componentWillUpdate

  render

  componentDidUpdate

17、当组件的key值发生改变后会执行哪些生命周期函数

  componentWillUnmount

  constructor

  componentWillMount

  render

  componentDidMount

 

18、在react中是否封装过组件?封装组件要注意的地方

  常用封装组件用到的东西

    propTypes  限制外部数据的类型

    defaultProps  设置默认的外部数据

    父传子  子传父  context等传值方式

    高阶组件

  封装组价要注意组件的复用性、灵活性

19、如何接收组件内部的标签/内容

  this.props.children

20、说一下对redux的理解,以及使用的方式

  其实redux就是Flux的一种进阶实现,它是一个应用数据流框架,主要作用是应用状态的管理。

  redux的三大原则:

    ①单一的数据源

    ②state是只读的

    ③使用纯函数来进行修改

  redux中常用的三个方法:

    ①createStore()  创建store

    ②combineReducers()  合并多个reducer

    ③applyMiddleware()  使用中间件,处理异步的action

  redux数据传递的流程:

    当组件需要改变store的时候,需要创建一个action,然后通过dispatch(action)传递给store,然后store把action转发给reducers。reducers会拿到previousState(以前的state数据)和action。然后将previousState和action进行结合做新的数据(store)修改。然后生成一个新的数据传递给store。store通过触发subscribe方法来调用函数执行setState使得view的视图发生改变。

21、请说下在react中如何处理异步的action

  通过applyMiddleware来使用中间件来处理action

  常用的中间件:

    redux-promise-middleware

    redux-thunk

    redux-saga

22、请说下对redux中间件的理解

  中间件:请求和回复之间的一个应用

  在redux中,中间件是dispatch和reducer之间的一个应用

23、请说下redux中你对reducers的理解,以及如何合并多个reducers

  在redux中reducer是一个纯函数,其中这个纯函数会接收2个参数,一个是state,一个是action。state用来保存公共的状态,state的特点是只能读不能修改。

  在实际开发中因为会涉及到多人协作开发,所以每个模块都有一个reducer,我们可以通过combineReducers来合并多个reducers。

24、请说下对高阶组件的理解,以及作用

  高阶组件:它是一个函数,接收一个组件作为参数,返回一个相对增强性的组件。

  高阶组件是一个函数,并不是组件。

  作用:

    ①属性代理----主要进行组件的复用(最常见的高阶组件的使用方式,通过做一些操作,将被包裹组件的props和新生成的props一起传递给此组件)

    ②反向继承----主要进行渲染的劫持(返回的react组件继承了被传入的组件,所以它能访问到的区域、权限更多,想比属性代理的方式,它更像是打入组件内部,对其进行修改)

25、在react中如何解决单页面开发首次加载白屏现象

  ①通过路由懒加载的方式  react-loadable

  ②首屏服务端渲染

26、请说下react中key值的理解

  react利用key来识别组件,它是一种身份标识,相同的key值react认为是同一个组件,这样后续相同的key对应的组件都不会被创建。

  有了key属性后,就可以与组件建立一种对应关系,react根据key来决定是销毁重新创建组件还是更新组件。

  key相同,若组件属性有所变化,则react只更新组件对应的属性,没有变化则不更新。

  key值不同,则react先销毁该组件(有状态组件的componentWillUnmount会执行),然后重新创建该组件(有状态组件的constructor和componentWIllUnmount都会执行)。

27、组件第一次执行的时候会执行哪些生命周期函数

  constructor

  componentWillMount

  render

  componentDidMount

  

28、哪些声明周期会执行多次

  render

  componentWillReceiveProps

  shouldComponentUpdate

  componentWillUpdate

  componentDidUpdate

29、当this.state和this.props执行的时候会执行哪些生命周期函数

  this.state

    shouldComponentUpdate

    componentWillUpdate

    render

    componentDidUpdate

  this.props

    componentWillReceiveProps

    shouldComponentUpdate

    render

    componentDidUpdate

  

30、谈谈对context的理解

  当不想在组件树中通过逐层传递props或state的方式来传递数据时,可以使用context来实现跨层级的组件数据传递,使用context可以实现跨组件传递。

  旧版context的基本使用:

    ①getChildContext根组件中声明,一个函数,返回一个对象,就是context

    ②childContextTypes根组件中声明,指定context的结构类型,如不指定会产生错误

    ③contextTypes子孙组件中声明,指定要接收的context的结构类型,可以只是context的一部分结构。contextTypes没有定义,context将是一个空对象。

    ④this.context在子孙组件中通过此来获取上下文

  新版context的使用:

    ①根组件中引入GlobalContext,并使用GlobalContext.Provider(生产者)

    ②组件引入GlobalContext并调用context,使用GlobalContext.Consumer

31、谈谈对react中withRouter的理解

  默认情况下必须是经过路由匹配渲染的组件在this.props上拥有路由参数,才能使用编程式导航的写法,withRouter是把不通过路由切换过来的组件,将react-router的history、location、match三个对象传入props对象上。

  简单来说就是:不是路由包裹的组件也可以使用路由的一些方法

32、说说对puerComponent的理解

  puerComponent表示一个纯组件,可以用来优化react程序,减少render函数渲染的次数,提高性能。

  puerComponent进行的是浅比较,也就是说如果是引用数据类型的数据,只会比较不是同一个地址,而不会比较这个地址里的数据是否一致。

  好处:当组件更新时,如果组件的props或state都没有改变,render函数就不会触发,省去虚拟DOM的生成和对比过程,达到提升性能的目的。具体原因是react自动帮我们做了一层浅比较。

33、react请求接口数据是在componentDidMount还是componentWillMount周期好

  如果你要获取外部数据并加载到组件上,只能在组件“已经”挂载到真是的网页上才能做这件事,其他情况你是加载不到组件的。componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以保证数据的加载。

  react异步渲染开启的时候,componentWillMount就可能中途被打断,中断之后渲染又要重新做一遍,如果在componentWillMount中做ajax调用,代码里看到只有调用一次,但是实际上可能调用n多次,这个浪费了性能。如果把ajax放在componentDidMount中,因为componentDidMount在第二阶段,所以绝对不会多次重复调用,这里是ajax合适的位置。

   

34、react性能优化

  一、immutable简介

    Immutable Data是一旦创建,就不能修改的数据。对Immutable对象的任何修改或添加删除操作都会返回一个新的Immutable对象。Immutable实现的原理是Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变,同时为了避免deepCopy把所有的节点都复制一遍带来的性能损耗。

  在js中,引用类型的数据,优点在于频繁的操作数据都是在原对象的基础上修改,不会创建新对象,从而可以有效的利用内存,不会浪费内存,这种特性称为mutable(可变),但恰恰它的优点也是它的缺点,太过于灵活多变在复杂数据的场景下也造成了它的不可控性,假设一个对象在多处用到,在某一处不小心修改了数据,其他地方很难预见到数据是如何改变的,针对这种问题的解决方法,一般就像刚才的例子,会想复制一个新对象,再在新对象上做修改,这无疑会造成更多的性能问题以及内存浪费。

  为了解决这种问题,出现了immutable对象,每次修改immutable对象都会创建一个新的不可变对象,而老的对象不会改变。

  二、react中如何减少render函数渲染的次数

    在react中当this.state、this.props发生改变的时候render函数就会执行,但有些时候this.state、this.props没有发生改变的时候render函数也会执行。那么如何减少render函数的执行次数,可以封装一个BaseComponent来减少react中render函数的执行次数。

import React,{Component}from 'react';
import {is} from 'immutable'; class BaseComponent extends Component {
shouldComponentUpdate(newProps, newState) {
const thisProps = this.props || {};
const thisState = this.state || {};
newState = newState || {};
newProps = newProps || {}; if (Object.keys(thisProps).length !== Object.keys(newProps).length ||
Object.keys(thisState).length !== Object.keys(newState).length) {
return true;
} for (const key in newProps) {
if (!is(thisProps[key], newProps[key])) {
return true;
}
} for (const key in newState) {
if (!is(thisState[key], newState[key])) {
return true;
}
}
return false;
}
} export default BaseComponent;

    继承BaseComponent来创建开发中所需要的组件:

import BaseComponent from  "@common/BaseComponent";

export default class Home extends BaseComponent{
constructor(){
super()
}
........
}

35、react中key值的作用

  react中的key属性,它是一个特殊的属性,它的出现不是给开发者使用的,而是给react自己使用,有了key属性后,就可以与组件建立一种对应关系。react利用key来识别组件,它是一种身份标识,就像每个人都有身份证一样,每个key对应一个组件,相同的key react认为是同一个组件,这样后续相同的key对应的组件都不会被创建。

  key值相同:如果两个元素的key相同,且满足第一点元素类型相同,若元素属性有所变化,则react只更新组件对应的属性,这种情况下性能开销会相对较小。

  key值不相同:在render函数执行的时候,新旧两个虚拟DOM会进行对比,如果两个元素有不同的key,那么前后两次渲染中就会被认为是不同的元素,这时候旧的那个元素会被销毁,新的元素会被创建。

//更新前
render(){
return(
<List key="1"/>
)
}
//更新后
render(){
return(
<List key="2"/>
)
}

  例子:

  //tree1
  <ul>
   <li key="1">1</li>
   <li key="2">2</li>
  </ul>
  //tree2
  <ul>
   <li key="1">1</li>
   <li key="3">3</li>
   <li key="2">2</li>
  </ul>

  如果没有key值,react并不会执行插入操作,它会直接移除原先的第二个子元素,然后在append进去剩下的子元素,而其实我们这个操作只需要一个insert操作就能完成。为了解决这种问题,react需要我们提供一个key来帮助更新,减少性能开销。

  如果有key值,react就会通过key来发现剩下tree2的第二个子元素不是原先tree1的第二个元素,原先的第二个元素被挪到下面去了,因此在操作的时候就会直接指向insert操作,来减少DOM操作的性能开销。

  不推荐用属性中的index来做key值

    大部分情况下我们要在执行数据遍历的时候会用index来表示元素的key,这样做其实并不是很合理。我们用key的真实目的是为了标识前后两次渲染中元素的对应关系,防止发生不必要的更新操作。那么如果我们用index来标识key,数据在执行插入、排序等操作之后,原先的index并不再对应到原先的值,那么这个key就失去了本身的意义,还会带来其他问题。

  注意事项

    react中的key值必须保证其唯一和稳定性

    下面案例中的key值以Math.random()随机生成而定,这使得数组元素中的每项都重新销毁然后重新创建,有一定的性能开销

  {
   dataList.map((item,index)=>{
   return <div key={Math.random()}>{item.name}</div>
   })
  }

  

  

知识点总结 REACT的更多相关文章

  1. react生命周期知识点

    react生命周期知识点 一个React组件的生命周期分为三个部分:实例化.存在期和销毁时. 实例化 组件在客户端被实例化,第一次被创建时,以下方法依次被调用: 1.getDefaultProps2. ...

  2. react 属性与状态 学习笔记

    知识点:1.react 属性的调用 this.props.被调用的属性名 设置属性的常用方法:var props = { one: '123', two: 321}调用这个属性:<HelloWo ...

  3. React 与 React Native 底层共识:React 是什么

    此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React 与 React Native 结合学习的方法,此小节主要介绍 React 的底层原理与 ...

  4. react复习总结(1)--react组件开发基础

    这次是年后第一次发文章,也有很长一段时间没有写文章了.准备继续写.总结是必须的. 最近一直在业余时间学习和复习前端相关知识点,在一个公司呆久了,使用的技术不更新,未来真的没有什么前景,特别是我们这种以 ...

  5. vue.js 知识点(二)

    关于vue看到有很多的知识点和react有很多相近的地方,比如说路由还有一些简单的运用,但是又有一些不同,比如格式.还有写法的一些不同! 所以在这里我总结一下关于vue 关于路由的一些运用: 路由: ...

  6. react深入 - 手写实现react-redux api

    简介:简单实现react-redux基础api react-redux api回顾 <Provider store>把store放在context里,所有子组件可以直接拿到store数据 ...

  7. 一个基于React整套技术栈+Node.js的前端页面制作工具

    pagemaker是一个前端页面制作工具,方便产品,运营和视觉的同学迅速开发简单的前端页面,从而可以解放前端同学的工作量.此项目创意来自网易乐得内部项目nfop中的pagemaker项目.原来项目的前 ...

  8. React实战教程之从零开始手把手教你使用 React 最新特性Hooks API 打造一款计算机知识测验App

    项目演示地址 项目演示地址 项目代码结构 前言 React 框架的优雅不言而喻,组件化的编程思想使得React框架开发的项目代码简洁,易懂,但早期 React 类组件的写法略显繁琐.React Hoo ...

  9. 从0开始,手把手教你使用React开发答题App

    项目演示地址 项目演示地址 项目源码 项目源码 其他版本教程 Vue版本 小程序版本 项目代码结构 前言 React 框架的优雅不言而喻,组件化的编程思想使得React框架开发的项目代码简洁,易懂,但 ...

随机推荐

  1. 在jenkins中处理外部命令7z的异常

    powershell中有自己的异常捕获机制,但是在jenkins中处理第三方工具抛出的异常时,一直抓不到,疑惑了很久,本篇内容主要描述此次过程及解决方案. powershell可以处理外部异常 try ...

  2. axios 源码解析(下) 拦截器的详解

    axios的除了初始化配置外,其它有用的应该就是拦截器了,拦截器分为请求拦截器和响应拦截器两种: 请求拦截器    ;在请求发送前进行一些操作,例如在每个请求体里加上token,统一做了处理如果以后要 ...

  3. Django学习笔记(17)——BBS+Blog项目开发(1)验证码功能的实现

    本文主要学习验证码功能的实现,为了项目BBS+Blog项目打下基础. 为了防止机器人频繁登陆网站或者破坏分子恶意登陆,很多用户登录和注册系统都提供了图形验证码功能. 验证码(CAPTCHA)是“Com ...

  4. python 统计使用技巧

    python 统计使用技巧 # 1.不输入回车获取值 注:需要tty模块配合. fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) ...

  5. 【04】Nginx:rewrite / if / return / set 和变量

    写在前面的话 我们前面已经谈了编译安装,基本语法,日志处理,location 匹配,root / alias 的不同效果.这里我们主要谈谈 rewrite(重写)功能,顺便说说 nginx 中自带的变 ...

  6. mysql 开启慢查询及其用mysqldumpslow做日志分析

    mysql慢查询日志是mysql提供的一种日志记录,它是用来记录在mysql中相应时间超过阈值的语句,就是指运行时间超过long_query_time值的sql,会被记录在慢查询日志中.long_qu ...

  7. VM1059 bootstrap-table.min.js:7 Uncaught TypeError: Cannot read property 'classes' of undefined

    参考链接:https://blog.csdn.net/liuqianspq/article/details/81868283 1.阳光明媚的下午,我在写CRUD,让数据传到前端的时候,解析的时候报错了 ...

  8. C# 关于使用JavaScriptSerializer 序列化与返序列化的操作

    //开始解析  //引用 //using System.Web.Script.Serialization; JavaScriptSerializer js = new JavaScriptSerial ...

  9. 解决 Windows Server 2008 R2 上 Windows Update 无法失败,提示 8024402F

    1.同步服务器时间 2.打开 services.msc,停止 Windows Update Service 3.手动下载 KB3138615 补丁:https://support.microsoft. ...

  10. Python简单的get和post请求

    1.json 模块提供了一种很简单的方式来编码和解码JSON数据. 其中两个主要的函数是 json.dumps() 和 json.loads() , 要比其他序列化函数库如pickle的接口少得多. ...