React面试题

一,React简介

React.js 只是一个视图库
(1)声明式设计
(2)高效:通过对 DOM 的模拟,最大限度的减少与 DOM 的交互。
(3)灵活:可以与已知的框架或库很好的配合。
(4)JSX:是 js 语法的扩展,不一定使用,但建议用。
(5)组件:构建组件,使代码更容易得到复用,能够很好地应用在大项目的开发中。
(6)单向响应的数据流:React 实现了单向响应的数据流,从而减少了重复代码, 这也是解释了它为什么比传统数据绑定更简单。

2、React 优点
比较现实的优点:
1、React 速度很快:它并不直接对 DOM 进行操作,引入了一个叫做虚拟
DOM 的概念,安插在 javascript 逻辑和实际的 DOM 之间,性能好。
2、跨浏览器兼容:虚拟 DOM 帮助我们解决了跨浏览器问题,它为我们提供了标准化的 API。
3、一切都是 component:代码更加模块化,重用代码更容易,可维护性高。
4、单向数据流:Flux 是一个用于在 JavaScript 应用中创建单向数据层的架构,它随着 React 视图库的开发而被 Facebook 概念化。
5、同构、纯粹的 javascript:因为搜索引擎的爬虫程序依赖的是服务端响应而不是 JavaScript 的执行,预渲染你的应用有助于搜索引擎优化。
6、兼容性好:比如使用 RequireJS 来加载和打包,而 Browserify 和
Webpack 适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。
缺点:并不是一个完整的框架,基本都需要加上 React-Router 和 Flux才能写大型应用

react 从 16.0 的区别
1)是生命周期的改变
2)是 this.setState
3) react-Router
4) 以前是 jsx 现在是 js 文件格式5)声明组件方式 class
为什么从 16.0 改变生命周期
1)便利取属性和状态,直接继承直接 有 props 和 state 2)class 类语法

下面我从 constructor 构造函数开始,从参数,作用,用法各方面总结
1、constructor
constructor 参数接受两个参数 props,context
可以获取到父组件传下来的的 props,context,如果你想在 constructor 构造函数内部(注意是内部哦,在组件其他地方是可以直接接收的)使用 props 或 context,则需要传入,并传入 super 对象。
当然如果你只需要在构造函数内使用 props 或者 context,那么只传入一个参数即可,如果都不可以,就都不传。
关于 ES6 的 class constructor 和 super
只要组件存在 constructor,就必要要写 super,否则 this 指向会错误

vue 和 react 的区别
(1)React 严格上只针对 MVC 的 view 层,Vue 则是 MVVM 模式
(2)irtual DOM 不一样,vue 会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树.而对于
React 而言,每当应用的状态被改变时,全部组件都会重新渲染,所以 react 中会需要
shouldComponentUpdate 这个生命周期函数方法来进行控制
(3)组件写法不一样, React 推荐的做法是 JSX + inline style, 也就是把 HTML 和 CSS 全都写进
JavaScript 了,即’all in js’; Vue 推荐的做法是 webpack+vue-loader 的单文件组件格式,即
html,css,jd 写在同一个文件;
(4)数据绑定: vue 实现了数据的双向绑定,react 数据流动是单向的
(5)state 对象在 react 应用中不可变的,需要使用 setState 方法更新状态;在 vue 中,state 对象不是必须的,数据由 data 属性在 vue 对象中管理

19 双向数据绑定和单向数据的区别?
1.单向数据流中,父组件给子组件传递数据,但反过来不可以传递,也就是说单向数据流是从最外层节点传递到子节点,他们只需从最外层节点获取 props 渲染即可,如果顶层组件的 某个
prop 改变了,React 会递归的向下便利整棵组件树,重新渲染所有使用这个属性的组件, React 组件内部还具有自己的状态,这些状态只能在组件内修改;双向数据绑定是数据与视图 双向绑定, 数据发生改变时,视图也改变,视图发生改变时,数据也会发生改变。
2.双向数据绑定的各种数据相互依赖相互绑定,导致数据问题的源头难以被跟踪到;单向 数据流的数据流动方向可以跟踪,流动单一,追查问题的时候可以更快捷,缺点是写起来不太方便, 要使视图发生改变就得创建各种 action 来维护 state。
3.双向绑定把数据变更的操作隐藏在框架内部,调用者并不会直接感知。而在践行单向数 据流的 flux 系的实现中,其实不过是在全局搞了一个单例的事件分发器(dispatcher),开发者 必须显式地通过这个统一的事件机制做数据变更通知。

二,react 生命周期

函数

1.初始化阶段:
getDefaultProps:获取实例的默认属性getInitialState:获取每个实例的初始化状态
componentWillMount:组件即将被装载、渲染到页面上
render:组件在这里生成虚拟的 DOM 节点
componentDidMount:组件真正在被装载之后二、运行中状态:
componentWillReceiveProps:组件将要接收到属性的时候调用
shouldComponentUpdate:组件接受到新属性或者新状态的时候(可以返回 false,
接收数据后不更新,阻止 render 调用,后面的函数不会被继续执行了)
componentWillUpdate:组件即将更新不能修改属性和状态
render:组件重新描绘
componentDidUpdate:组件已经更新三、销毁阶段:
compcomponentWillUnmount:组件即将销毁

2.react 性能优化是哪个周期函数?
shouldComponentUpdate 这个方法用来判断是否需要调用 render 方法重新描绘
dom。因为 dom 的描绘非常消耗性能,如果我们能在 shouldComponentUpdate 方法中能够写出更优化的 dom diff 算法,可以极大的提高性能。
详细参考:https://segmentfault.com/a/1190000006254212

一、react 有哪几个生命周期?(10 个)
分为三个阶段,初始化,运行中,销毁 初始阶段先执行
getDelfaultProps(组件想要拥有默认属性可以通过这个钩子函数设置)
getInitialState(组件想要拥有状态只能通过这个钩子函数)
componentWillMount(做一些初始数据的获取和设置,并且在这里更改数据不会触发运行阶段的钩子函数,在这里还可以更改 this 的指向问题)
render(构建组件的虚拟 DOM 结构进行编译)
componentDidMount(这里可以操作DOM,并且可以访问已经渲染的DOM,在这个钩子函数里面也可以进行对数据的获取) 初始化阶段结束 生命周期进入运行阶段
componentWillReceiveProps(nextProps)(当接收到的属性发生变化时触发,可以在这里更改改变后的属性去做一些事情,比如更改自己的状态,在这里 this 上的属性还没有更新,要想使用新的数据需要从参数中得到) shouldComponentUpdate(props,state) (当属性或状态改变的时候都会触发,参数接收到最新的属性和状态, 这个钩子函数会默认 return true ,false 的话会阻止生命周期向下执行,在这里我们可以做一些性能优
化) componentWillUpdate(props,state) (多做一些调试工作,在 props 和 state 发生改变的时候执行,并且在 render 方法之前执行,但是你在这个钩子函数里不能更改状态,否则会造成死循环)
componentDidUpdate(组件的更新结束后执行,在这里可以操作更新完成后的 dom) 运行阶段结束 生命周期进入销毁阶段
componentWillUnmont (在销毁前触发,主要进行善后工作,清空计时器,事件解绑等…)
二、在哪个生命周期做优化?
shouldComponentUpdate 做判断,判断当前state跟下一个state是否相同来决定是否渲染

三,虚拟DOM

一百六十三、为什么虚拟 dom 会提高性能?
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提髙性能。
具体实现步骤如下:
1. 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的

DOM 树,插到文档当中
2.当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
3.把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。参考链接:https://www.zhihu.com/question/29504639?sort=created
一百六十四、diff 算法?
1)把树形结构按照层级分解,只比较同级元素。
2)给列表结构的每个单元添加唯_的 key 属性,方便比较。
3)React 只会匹配相同 class 的 component (这里面的 class 指的是组件的名字)
4)合并操作,调用 component 的 setState 方法的时候,React 将其标记为 dirty.到每一个事件循环 结束,React 检查所有标记 dirty 的 component 重新绘制.
5)选择性子树渲染。开发人员可以重写 shouldComponentUpdate 提高 diff 的性能。参考链接:https://segmentfault.com/a/1190000000606216

三、react 怎么从虚拟 dom 中拿出真实 dom?
(在节点中设置 ref 通过 this.refs.[refname])

四、react 的 diff 算法是怎么完成的?
(分层对比,把DOM 树按层级拆分,简化了复杂度,只比较同级元素,只匹配相同组件名字的组件,给列表结构的每个单元添加唯一的key 属性,方便比较(为什么不用index,如果用index的话追加在后面不会影响,如果追加到前面会影响性能))
五、Redux 的流程,React 中的 props 和 state 的用法
(使用通过 reducer 创建出来的 Store 发起一个 Action,reducer 会执行相应的更新 state的方法,每当 state 更新之后,view 会根据 state 做出相应的变化!)
getDefaultProps(用来设置组件的默认属性) getInitialState(用来设置组件的状
态)
中间件(thunks:处理异步操作 saga:saga 相当于在 redux 原有的数据流中多了一层
监控,捕获监听到的 action,进行处理后,put 一个新的 action 给相应的 reducer 去处理。 logger:提供日志输出 devtools:它可以让你实时的监控 Redux 的状态树的 Store)

十九、react 虚拟 DOM 实现原理 !!
在浏览器端用 javascript 实现一套 DOMAPI,基于 react 进行开发时所有的 DOM 操作都是通过虚拟 dom 进行的,当数据变化时,react 都会重新构建整个 dom 树,然后 react 将当前整个 dom 树与上一次的 dom 树进行对比,得到 dom 结构的区别,然后仅仅将需要变化的部分进行实际的浏览器 dom 更新。

  1. 虚拟 dom 实现的原理以及怎么实现,
    虚拟 dom 相当在 js 和真实 dom 中间加了一个缓存 , 利用 dom diff 算法避免了没有必要的 dom 操作 , 从而提高性能
    用 javaScript 对象 结构表示 dom 树的结构;然后用这个树构建一个真正的 dom 树,插到文档中
    当状态变更的时候,重新构建一颗新的对象树。然后用新的树和旧的树进行比较,记录两颗树的差异
    把记录的差异之处重新进行 dom 渲染 视图就更新了
    diff 算法
    (1)把树形结构按照层次分解,之比较同级元素
    (2)给列表结构的每个单元添加唯一的 key 属性 比较 key 值
    (1)react 只会匹配相同组件的 component
    (4)合并操作,调用 component 的 setState 方法的时候,react 将其标记 dirty 到每一个事件循环,结束 react
    检查所有标记 dirty 的 component 重新绘制
    (5)选择性子树渲染。用 shouldComponentUpdate 提高 diff 算法 、

七、react 单向数据流程:
这是一个 React 组件实现组件可交互所需的流程,render()输出虚拟
DOM,虚拟 DOM 转为 DOM,再在 DOM 上注册事件,事件触发 setState()修改数据,在每次调用 setState 方法时,React 会自动执行 render 方法来更新虚拟 DOM,如果组件已经被渲染,那么还会更新到 DOM 中去

9.虚拟 dom 实现的原理以及怎么实现,
虚拟 dom 相当在 js 和真实 dom 中间加了一个缓存 , 利用 dom diff 算法避免了没有必要的 dom 操作 , 从而提高性能
用 javaScript 对象 结构表示 dom 树的结构;然后用这个树构建一个真正的
dom 树,插到文档中
当状态变更的时候,重新构建一颗新的对象树。然后用新的树和旧的树进行比较,记录两颗树的差异
把记录的差异之处重新进行 dom 渲染 视图就更新了
可以去参考:https://www.zhihu.com/question/29504639?sort=created
10.diff 算 法
(1)把树形结构按照层次分解,之比较同级元素
(2)给列表结构的每个单元添加唯一的 key 属性 比较 key 值
(3)react 只会匹配相同组件的 component
(4)合并操作,调用 component 的 setState 方法的时候,react 将其标记 dirty 到每一个事件循环,结束 react
检查所有标记 dirty 的 component 重新绘制
(5)选择性子树渲染。用 shouldComponentUpdate 提高 diff 算法 、redux 的流程:
1.store 通过 reducer 创建了初始状态
2.iew 通过 store.getState()获取到了 store 中保存的 state 挂载在了自己的状态上
3.用户产生了操作,调用了 actions 的方法
4.actions 的方法被调用,创建了带有标示性信息的 action
5.actions 将 action 通过调用 store.dispatch 方法发送到了 reducer 中6.reducer 接收到 action 并根据标识信息判断之后返回了新的 state
7.store 的 state 被 reducer 更改为新 state 的时候,store.subscribe 方法里的回调函数会执行,此时就可以通知 view 去重新获取 state
注意:flux、redux 都不是必须和 react 搭配使用的,因为 flux 和 redux 是完整的架构,在学习 react 的时候,只是将 react 的组件作为 redux 中的视图层去使用了

四,Redux 中间件

Redux 的流程,React 中的 props 和 state 的用法(使用通过 reducer 创建出来的 Store 发起一个 Action,reducer 会执行相应的更新 state 的方法,每当 state更新之后,view 会根据 state 做出相应的变化!)
redux 的流程:
1.store 通过 reducer 创建了初始状态
2.iew 通过 store.getState()获取到了 store 中保存的 state 挂载在了自己的状态上
3.用户产生了操作,调用了 actions 的方法4.actions 的方法被调用,创建了带有标示性信息的 action
5.actions 将 action 通过调用 store.dispatch 方法发送到了 reducer 中
6.reducer 接收到 action 并根据标识信息判断之后返回了新的 state

7.store 的 state 被 reducer 更改为新 state 的时候,store.subscribe 方法里的回调函数会执行,此时就可以通知 view 去重新获取 state
注意:flux、redux 都不是必须和 react 搭配使用的,因为 flux 和 redux 是完整的架构,在学习 react 的时候,只是将 react 的组件作为 redux 中的视图层去使用了

Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
Redux 提供 createStore 这个函数,用来生成 Store。

Store 对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。 当前时刻的 State,可以通过 store.getState()拿到

store.subscribe 方法设置监听函数,一旦 State 发生变化,就自动执行这个函

stroe 的实现提供了三个方法
store.getState()
store.dispatch()
store.subscribe()

一百五十八、redux 中间件
中间件提供第三方插件的模式,自定义拦截 action 一> reducer 的过程。变为 action
一〉 middlewares 一> reducer。这种机制可以让我们改变数据流,实现如异步 action,

action 过滤,日志输出,异常报告等功能。常见的中间件:
redux 一 logger:提供日志输出
redux 一 thunk:处理异步操作
redux 一 promise:处理异步操作,actionCreator 的返回值是 promise
一百五十九、redux 有什么缺点
1.一个组件所需要的数据,必须甶父组件传过来,而不能像 flux 中直接从 store
取。
2.当一个组件相关数据更新吋,即使父组件不需要用到这个组件,父组件还是会重新 render,可能会 有效率影响,或者需要写复杂的 shouldComponentUpdate 进行判断。

六、比较 redux 和 vuex 的区别
(1.vuex 是 redux 的基础上进行改变,对仓库的管理更加明确。2.使用 mutation 来替换 redux 中的 reducer。 3.vuex 有自动渲染的功能,所以不需要更新。4.vuex 是专门为 vue提供的状态管理工具,而 redux 是一个泛用的状态管理框架。)

十一、react-redux 的实现原理(react 框架)!!
(使用通过 reducer 创建出来的 Store 发起一个 Action,reducer 会执行相应的更新 state的方法,每当 state 更新之后,view 会根据 state 做出相应的变化!)

react-redux 将所有组件分成两大类:UI 组件和容器组件
UI 组件有以下几个特征:
(1)只负责 UI 呈现,带任何业务逻辑
(2)没有状态(即不适用 this.state 这个变量)
(3)搜有数据都由参数(this.props)提供
(4)不适用任何 redux 的 API 容器组件与 UI 组件相反

你可能会问,如果一个组件既有 UI 又有业务逻辑,那怎么办?回答是,将它拆分成下面的结构:外面是一个容器组件,里面包了一个 UI 组件。前者负责与外部的通信,将数据传给后者, 由后者渲染出视图。

React-Redux 规定,所有的 UI 组件都由用户提供,容器组件则是由 React-Redux 自动生成。也就是说,用户负责视觉层,状态管理则是全部交给它。

五、一句话总结 UI 组件和容器组件:
UI 组件只负责页面,没有业务逻辑
容器组件 dispatch{}取数据,action 传给 store,store 调用
reducer,reducer 返回拷贝完的 newstate,交给 store。Store 再把数据给component,刷新页面

五, Flux

一百六十六、简述 flux 思想
Flux 的最大特点,就是数据的"单向流动"。
1.用户访问 View
2.View 发 出 用 户 的 Action 3.Dispatcher 收到 Action,要求 Store 进行相应的更新
4.Store 更新后,发出一个"change"事件
5.View 收到"change"事件后,更新页面
参考链接:http://www.ruanyifeng.com/blog/2016/01/flux.html

Flux
Redux 的作用跟 Flux 是一样的,它可以看作是 Flux 的一种实现不同点:
Redux 只有一个 store 而 Flux 有多个
Redux 有 dispatch 而 Flux 没有
Flux 是一种应用架构,或者说是一种思想,它跟 React 本身没什么关系,它可以用在 React 上,也可以用在别的框架上。前面说到 Flux 在 React 中主要用来统一管理引起 state 变化的情况。Flux 维护着一个或者多个叫做 Store 的变量,就像 MVC 里面的 Model,里面存放着应用用到的所有数据,当一个事件触发时 ,Flux 对事件进行处理,对 Store 进行更新,当 Store 发生变化时,通常是由应用的根组件(也叫 controller view)去获取最新的 store,然后更新state,之后利用 React 单向数据流的特点一层层将新的 state 向下传递实现 view 的更新。这里的 controller view 可以有多个也可以不是根组件,但是这样数据流维护起来就比较麻烦

Flux 主要包括四个部分,Dispatcher、Store、View、Action,其中 Dispatcher 是 Flux 的核心枢纽,它相当于是一个事件分发器,将那些分散在各个组件里面的逻辑代码收集起来,统一在 Dispatcher 中进行处理。完整的 Flux 处理流程是这样的:用户通过与 view 交互或者外部产生一个 Action,Dispatcher 接收到 Action 并执行那些已经注册的回调,向所有 Store 分发
Action。通过注册的回调,Store 响应那些与他们所保存的状态有关的 Action。然后 Store 会触发一个 change 事件,来提醒 controller-views 数据已经发生了改变。Controller-views 监听这些事件并重新从 Store 中获取数据。这些 controller-views 调用他们自己的 setState() 方法,重新渲染自身以及组件树上的所有后代组件。使用 Flux 有个好处就是我只需要用 action 对象向 Dispatcher 描述当前的事件就可以执行对应的逻辑,因为 Dispatcher 是所有 Action 的处理中心,即使没有对应的事件发生,我们也可以“伪造”一个出来,非常利于测试

六,router

五十六、react-router 的原理
通过监听 onHashChange 事件,监听地址栏 Url 的改变。然后根据 url 的改变切换对应组件
(监视 url 的改变,然后加载对应的组件 )
六十、React 按需加载
react 按需加载,关键是让路由动态加载组件,react-router 提供了一个属性getComponent ,它与 component 属性一样,但是是异步的,当路由匹配时才会调用这个方法,常用于代码分割;

react-router 的原理React-router
市场上的 react-router 的版本有 1、2、3、4,1-3 的差别不大,使用于 16.0.0 以下的版本react-router 4.0 适用于 16.0.0 以上
React.createClass 来创建组件,在 16 以上只能使用 class 类的方式来创建
实现 url 与 ui 界面的同步,其中在 react-router 中,url 对应 location 对象,而 ui 是由 react
components 来决定的,这样就转变成 location 与 components 之间的同步问题
react-router 依赖基础 - history
老浏览器的 history: 主要通过 hash 来实现,对应 createHashHistory

高版本浏览器: 通过 html5 里面的 history,对应 createBrowserHistory
实现 URL 与 UI 界面的同步。其中在 react-router 中,URL 对应 Location 对象,而 UI是由 react components 来决定的,这样就转变成 location 与 components 之间的同步问题。 react-router 在 history 库的基础上,实现了 URL 与 UI 的同步,分为两个层次来描述
具体的实现。
location
location 是指你当前的位置,将要去的位置,或是之前所在的位置
match
match 对象包含了 如何与 URL 匹配的信息

一个使用了 HTML5 history API 的高阶路由组件,保证你的 UI 界面和 URL 保持同步

六,性能优化

21.react 项目性能怎么优化:
redux 尽量减少共通管理的数据
常见 js 的优化原则,减少链式调用,及时跳出循环循环生成列表的时候要有 key 值
shouldComponentUpdate 减少不必要的 dom 更新操作(选择性子树渲染)
22.页面性能优化。
页面的性能优化在 shouldComponentUpdate 钩子函数中利用 key 值得不同来识别组件的变化
减少请求
整合资源就是把公共样式 和 公用 js 文件放在一起实现多个页面共享图片的整合 可以用精灵图
使用浏览器缓存减少重定向请求
这个还有很多 自主查找 学校发蓝色本里也有

页面加载速度的优化减少请求
整合资源
使用浏览器缓存和本地缓存取消重定向
代码简介调整图片
延迟读取和执行的脚本使用 ajax 来增强进程

一百六十五、react 性能优化方案
1)重写 shouldComponentUpdate 来避免不必要的 dom 操作 0
2)使用 production 版本的 react.js0
3)使用 key 来帮助 React 识别列表中所有子组件的最小变化。参考链接:
https://segmentfault.com/a/1190000006254212
http://blog.csdn.net/limm33/article/details/50948869

三十三、react 可以在哪个生命周期中做性能优化
shouldComponentUpdate:做判断,判断当前 state 跟下一个 state 是否相同来决定是否渲染

一百五十四、React 图片加载优化处理:
懒加载,图片压缩,放在 CDN,精灵图

七,高阶组件

高阶组件
高阶组件通过包裹被传入的 React 组件,经过一系列处理,最终返回一个相对增强的 React 组件,供其他组件调用 可以说跟 widthRoute 一样的
就是相当于的一个路由的升级版 可以不破坏以前路由的效果 并增强效果 相当于判断登录和注册页面的切换 (就是权限路由)
权限路由就是路由跳转时 返回一个 三目判断 用来增强 route 的功能
4.高阶组件
其实对于一般的中小项目来说,你只需要用到以上的这三种组件方式就可以很好地构造出所需的应用了。但是当面对复杂的需求的时候,我们往往可以利用高阶组件(Higher-Order
Component)编写出可重用性更强的组件。那么什么是高阶组件呢?其实它和高阶函数的概念类似,就是一个会返回组件的组件。或者更确切地说,它其实是一个会返回组件的函数。就像这样:
const HigherOrderComponent = (WrappedComponent) => { return class WrapperComponent extends Component { render() {
//do something with WrappedComponent
}
}
}
做为一个高阶组件,可以在原有组件的基础上,对其增加新的功能和行为。我们一般希望编写的组件尽量纯净或者说其中的业务逻辑尽量单一。但是如果各种组件间又需要增加新功能,如打印日志,获取数据和校验数据等和展示无关的逻辑的时候,这些公共的代码就会被重复写很多遍。因此,我们可以抽象出一个高阶组件,用以给基础的组件增加这些功能,类似于插件的效果。
5.Render Callback 组件
还有一种组件模式是在组件中使用渲染回调的方式,将组件中的渲染逻辑委托给其子组件。就像这样:
import { Component } from “react”;
class RenderCallbackCmp extends Component { constructor(props) {
super(props); this.state = { msg: “hello”
};
}

render() {
return this.props.children(this.state.msg);
}
}
const ParentComponent = () => (
{msg =>
//use the msg

{msg}
} ); 父组件获取了内部的渲染逻辑,因此在需要控制渲染机制时可以使用这种组件形式。

高阶组件
高阶组件通过包裹被传入的 React 组件,经过一系列处理,最终返回一个相对增强的 React 组件,供其他组件调用 可以说跟 widthRoute 一样的
就是相当于的一个路由的升级版 可以不破坏以前路由的效果 并增强效果 相当于判断登录和注册页面的切换 (就是权限路由)
权限路由就是路由跳转时 返回一个 三目判断 用来增强 route 的功能高阶组件其实就是处理 react 组件的函数

17.纯函数
Reducer 函数最重要的特征是,它是一个纯函数,也就是说,只要是同样的输入, 必定得到同样的输出。
纯函数是函数式编程的概念,必须遵守以下一些约束

八,props和state

24、prop 和 state 的区别
props是一个父组件传递给子组件的数据流,这个数据流可以一直传递到子孙组件。而state代表的是一个组件内部自身的状态(可以是父组件、子孙组件)。
改变一个组件自身状态,从语义上来说,就是这个组件内部已经发生变化,有可能需要对此组件以及组 件所包含的子孙组件进行重渲染。
props放初始化数据,一直不变的,state就是放要变的。
props一般用于父组件向子组件通信,在组件之间通信使用
state一般用于组件内部的状态维护,更新组件内部的数据,状态,更新子组件的props

props 和 state 改变时,触发那些生命钩子
子组件通过接收 props 来进行渲染,每次 props 改变都会重新 render。
组件中的 props 是一种父级向子级传递数据的方式.

1.state 的作用
state 是 React 中组件的一个对象.React 把用户界面当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界面与数据保持一致.
React 中,更新组件的 state,会导致重新渲染用户界面(不要操作 DOM).简单来说,就是用户界面会随着 state 变化而变化.

2.state 工作原理
常用的通知React 数据变化的方法是调用setState(data,callback).这个方法会合并
data 到 this.state,并重新渲染组件.渲染完成后,调用可选的callback 回调.大部分情况不需要提供 callback,因为 React 会负责把界面更新到最新
状态.

props 和 state 的共同点
props 和 state 都 是 纯 JS 对 象
props 和 state 的改变都会触发 render 函数来更新界面
props 和 state 都是确定的。 如果你的组件在相同的 props 和 state 的组合下产生不同结果,那一定是哪里错了。
组件中的传参
有三种方式:
我们可以给指定一个 path 也可以用 history Link NavLink
query 类似于 get 方法
state 方式类似于 post 方式
组件之间传值
也有三种
props 父子之间
state 子 到 父兄弟组件用事件

一百五十一、Setstate: 同步异步
异步
为什么:如果是同步的话,碰到开发者高频率调用 setState 方法,比如在一个回调函数中调用多个函数,每个函数都调用一次 setState,React 会频繁渲染,性能和体验都很差,所以采用了异步更新的方式,将数次变动集中起来更新。

避免这个异步更新问题的方法有两种,一是采用楼上说的回调函数,二是 setState 传入一个函数,如下
this.setState({xxxxx},function(){
//查看改变后的值
})
this.setState(prevState=>({
…prevState, [propYouWantToChange]:valueYouWantToChange
}))
一百五十二、Setstate 哪个生命周期不能用:
componentWillUpdate 中不能使用,因为在 state 改变后会再次调用这个方法,会使程序陷入死循环

1.state 发生变化,react 会触发哪些生命周期 shouldComponentUpdate => componentWillUpdate => render =>componentDidUpdateps:
2.如果回答的是 shouldComponentUpdate => render
=>getSnapshotBeforeUpdate => componentDidUpdate , 那差不多应该有高级,这是最新的生命周期函数
如果一个 react 组件 key 值改变了,会经历哪些生命周期函数componentwillunmount => componentwillmount => render
=>componentDidMount

setState
setState 就会以异步的方式执行。一般理解为 this.state 的值会在 DOM 中渲染,其他的情况比如取 token,作为接口的参数的你 setState 是同步的

setState()是异步的
this.setState()会调用 render 方法,但并不会立即改变 state 的值,state 是在 render 方法中赋值的。所以执行 this.setState()后立即获取 state 的值是不变的。同样的直接赋值 state 并不会触发更新,因为没有调用 render 函数。
组件卸载之前,加在 dom 元素上的监听事件,和定时器需要手动清除,因为这些并不在react 的控制范围内,必须手动清除。
js 中 dom 事件,自己有没有封装过组件好好编!!!

九,传值

二百〇九、react 组件之间如何传值?
(直接关系组件,间接关系组件,无关系组件) 一、【父组件】向【子组件】传值
初步使用
这个是相当容易的,在使用 React 开发的过程中经常会使用到,主要是利用 props 来进行交流
二、【子组件】向【父组件】传值
接下来,我们介绍【子组件】控制自己的 state 然后告诉【父组件】的点击状态,然后在【父组件】中展示出来。因此,我们添加一个 change 事件来做交互。

6.React 传递参数的多种方式

父子组件之间传递参数
父组件往子组件传值,直接用 this.props 就可以实现
在父组件中,给需要传递数据的子组件添加一个自定义属性,在子组件中通过 this.props 就可以获取到父组件传递过去的数据

子组件给父组件传值
子组件给父组件传值的话,需要在父组件设置接收函数和 state,同时将函数名通过 props 传递给子组件也就是给子组件传入父组件的方法,在子组件进行调用
7.constructor 里面的 super()是干嘛用的?
如果要在子类的 constructor 里使用 this,必须调用父类 constructor,否则就拿不到 this
那么问题就来了,如何调用父类的 constructor 呢? 通过 super()
如果要在 constructor 里使用父组件传递过来的参数,必须在调用父组件 super 时,传递参数给父组件的
constructor
如果不在 constructor 里面使用 this,或者参数,就不需要 super ;因为 React 以及帮你做了 this,props
的绑定

React 中 constructor 参数接受两个参数 props,context
可以获取到父组件传下来的的 props,context,如果你想在 constructor 构造函数内部(注意是内部哦,在组件其他地方是可以直接接收的)使用 props 或 context, 则需要传入,并传入 super 对象。
当然如果你只需要在构造函数内使用 props 或者 context,那么只传入一个参数即可,如果都不可以,就都不传。

九,坑

react 里面的坑。
常见的就是内联样式 他需要加双大括号就是 map 遍历的时候 必须加 key 值
return 不和 dom 元素同行的问题

初学踩坑
1.在 react 组件内引入 css 时,组件中的 className 需要通过引入的样式来声明,如果直接声明,那么 css 中相应的样式就不会起效。
原因: css modules 为了防止全局污染,会把 css 文件中的类名换为 hash 值,即原类名不存在,只能通过相应的 hash 值取得样式

CSS 模块化遇到了哪些问题全局污染
命名混乱
依赖管理不彻底无法共享变量 代码压缩不彻底

四十三、React 项目遇到的问题
在 react 项目中使用 Echarts 的时候,在 componentDidMount 中执行绘制图表的函数
echarts。Init(#id),提示获取不到宽高,因此,绘制出来的图标呈现出压扁的状态或者没有绘制
解决办法:给 compoentDidMount 中的 drawCharts 方法加上一个延时器

你可能感兴趣的:(React面试题)