state和props有什么区别 ?
state是组件自己管理数据,控制自己的状态,可变;
props是外部传入的数据参数,不可变;
没有state的叫做无状态组件,有state的叫做有状态组件;
无状态组件、纯组件
1.无状态组件是通过减少继承 Component 的生命周期函数来达到优化性能的效果,它本质上就是一个单纯的 render 函数。缺点:因为没有 shouldComponentUpdate 生命周期函数,所以每次组件更新都会触发 render 函数。它是一种只负责展示的纯组件,它的特点是不需要管理状态state,数据直接通过props传入,这也符合 React 单向数据流的思想。它一般配合高阶组件来使用。
2.纯组件是通过控制 shouldComponentUpdate 生命周期函数减少 render 调用次数来优化性能的。因为它只进行一层浅比较,即 props 和 state 的内存地址如果相同则 shouldComponentUpdate 返回 false。一般配合 Immutable 一起使用,保证数据的不变性。
- 在什么情况下优先选用 Class Component 而不是 Function Component ?
在组件需要包含内部状态或者使用到生命周期函数的时候使用 Class Component 否则使用 Function Component
受控组件和非受控组件
- “受控”与“非受控”两个概念,区别在于这个组件的状态是否可以被外部修改。
- 非受控组件状态并不会受应用状态的控制,应用中也多了局部组件状态,而受控组件的值来源于 state。
- 非受控组件的值不受组件自身的 state 或者 props 控制,通常需要为其添加 ref 来访问渲染后的底层 DOM 元素。
什么是 JSX ?
JSX 是 JavaScript XML 的简写。JSX 就是 Javascript 和 XML 结合的一种格式。React 发明了JSX ,从本质上讲,JSX 只是为 React.createElement(component, props, ...children) 函数提供的语法糖。
它可以让我们在 js 文件中写 html 代码,本质就是 babel 转译成 React.createElement 来执行,用来构建虚拟 dom
refs 的作用是什么 ?
refs 是 React 提供给我们的安全访问 DOM 元素或者某个组件实例的句柄。我们可以为元素添加 ref 属性然后再回调函数中接收该元素在 DOM 树中的句柄,该值会作为回调函数的第一个参数返回:
class CustomForm extends component{
handleSubmit = () => {
console.log('Input value: ', this.input.value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
ref={(input) => this.input = input}
/>
<button type='submit'>Submit</button>
</form>
)
}
}
上述代码中 input 包含了一个 ref 属性,该属性声明的回调函数会接收 input 对应的 DOM 元素,我们将其绑定到 this 指针以便在其它类函数中使用。另外,refs 并不是类组建的专属,函数式中同样能够利用闭包暂存其值:
function CustomForm ({hanldeSubmit}) {
let inputElement
return (
<form onSubmit={() => hanldeSubmit(inputElement.value)}>
<input
type='text'
ref={(input) => inputElement = input}
/>
<button type="submit">Submit</button>
</form>
)
}
下述需要使用 Refs 的情况:
1.需要管理焦点、选择文本或者媒体播放的时候
2.触发式动画
3.与第三方 DOM 库集成
设置:<input ref="myInput" /> React 和 Vue 都可以通过赋值字符串的形式赋值
使用:React --- this.refs.myInput,Vue --- this.$refs.input
React ref 属性也可以是一个回调函数而不是一个名字。 这个函数将要在组件被挂载之后立即执行。当这个参照组件被卸载并且这个ref改变的时候,先前的ref的参数值将为null。这将有效的防止了内存的泄露。这个生成和卸载时机 React 和 Vue 保持一致。
React 中 keys 的作用是什么 ?
key 的作用主要是为了高效的更新虚拟 DOM。
1.Keys 是 React 中用于追踪列表中哪些元素被修改、被添加、被移除等的辅助标志
2.在开发中我们要保证某个元素的 key 在同级元素中具有唯一性
3.在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新创建的还是被移动而来的元素,从而减少不必要的元素重渲染。
4.React 还需要借助 Key 来判断元素与本地状态的关联关系,因此我们绝不可忽视转换函数中 key 的重要性
概述下 React 中的事件处理逻辑
1.为了解决跨浏览器兼容性问题,React 会将浏览器原生事件 ( Browser Native Event ) 封装为合成事件 ( SyntheticEvent ) 传入设置的事件处理器中。这里的合成事件提供了与原生事件相同的接口,不过他们屏蔽了底层浏览器的细节差异,保证了行为的一致性
2.另外,React 并没有直接将事件附着到子元素上,而是单一事件监听器的方式将所有的事件发送到顶层进行处理。这样 React 在更新 DOM 的时候就不需要考虑如何去处理附着在 DOM 上的事件监听器,最终达到优化性能的目的
createElement 与 cloneElement 的区别 ?
createElement 函数是 JSX 编译之后使用的创建 React Element 的函数,而 cloneElement 则是用于复制某个元素并传入新的 Props
当组件的 setState 函数被调用之后,会发生什么 ?
在代码中调用setState函数之后,React 会将传入的参数对象与组件当前的状态合并,然后触发所谓的调和过程(Reconciliation)。 经过调和过程,React 会以相对高效的方式根据新的状态构建 React 元素树并且着手重新渲染整个UI界面。 在 React 得到元素树之后,React 会自动计算出新的树与老树的节点差异,然后根据差异对界面进行最小化重渲染。 在差异计算算法中,React 能够相对精确地知道哪些位置发生了改变以及应该如何改变,这就保证了按需更新,而不是全部重新渲染
传入 setState 函数的第二个参数的作用 ?
该函数会在 setState 函数调用完成并且组件开始重新渲染的时候被调用,我们可以用该函数来监听渲染是否完成:
this.setState({
userName: 'protein'
}, () => {
console.lot('setState has finished and the component has re-rendered.')
})
什么是 Fiber ?是为了解决什么问题 ?
1.官方解释:React Fiber 是对核心算法的一次重新实现。它改变了检测变更的方法和时机,借此可改进浏览器端和其他渲染设备的响应速度。
2.破解 JavaScript 中同步操作时间过长的方法其实很简单——分片。把一个耗时长的任务分成很多小片,每一个小片的运行时间很短,虽然总时间依然很长,但是在每个小片执行完之后,都给其他任务一个执行的机会,这样唯一的线程就不会被独占,其他任务依然有运行的机会。
3.React Fiber 把更新过程碎片化,每执行完一段更新过程,就把控制权交还给 React 负责任务协调的模块,看看有没有其他紧急任务要做,如果没有就继续去更新,如果有紧急任务,那就去做紧急任务。
什么是 HoC ( Higher-Order Component ) ?适用于什么场景 ?
它就是一种 react 的进阶使用方法,主要为了便于组件的复用解决一些交叉问题。HOC 本身并不是 React API 它就是一个可以接受组件为参数并且返回一个 增强组件的方法。
作用:
1.代码重用,逻辑和引导抽象
2.渲染劫持
3.状态抽象和控制
4.Props 控制
更多更详细讲解请戳这位大神的总结。。。
- 有时候我们会想要在组件之间重用一些状态逻辑。目前为止,有两种主流方案来解决这个问题:高阶组件和 render props。
父子组件之间的通讯
-
React实例 parent01.jsx child01.jsx child02.jsx
1.父组件向子组件传值 --- 直接通过props
2.子组件向父组件传值 --- 回调函数
3.父组件向子孙组件传值 --- context 如果一个组件设置了 context,那么它的子组件都可以直接访问到里面的内容,它就像这个组件为根的子树的全局变量。任意深度的子组件都可以通过 contextTypes 来声明你想要的 context 里面的哪些状态,然后可以通过 this.context 访问到那些状态。
4.兄弟组件之间的传值 --- 可以通过父组件实现传值,可以通过全局变量实现传值,还可以通过 PubSubJS 库实现 ( 类似于 PostMessage 跨域,还有 electron里面的主进程和渲染进程之间的通讯 ) ,如果是比较大型的项目,可以使用 react-redux 进行单一数据流的状态管理 -
Vue实例
1.父子组件之间 --- 属性通过 v-bind 形式绑定,子组件需要在 props 数组里面接收方可使用;方法通过 v-on 绑定,子组件通过 this.$emit('方法名', 参数) 来调用
2.兄弟组件传值 --- eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。或者直接上 Vuex。
Provider Consumer
你了解 VirtualDOM 吗,解释一下它的原理
1.它就是一个 JS 对象,最初是作为 real DOM 的副本。
2.它是一个节点树,将元素、属性及其内容作为对象的属性。
3.React 渲染函数从 React 组件中创建一个节点树,然后响应由用户或操作者系统完成的各种动作导致的数据模型中的变化来更新该树。
4.它经过如下三个简单的步骤:
1)每当数据改变,整个 UI 都将在 VirtualDOM 描述中重新渲染
2)通过 diff 算法对比新旧两棵树找出最小差异
3)完成计算后只将实际更改的部分渲染到页面上
怎样理解在 React 中一切皆组件?
组件是 React 应用 UI 的构建块,组件可以将整个 UI 分成很多独立的可以重用的部分,每个组件是独立的不影响 UI 的其它部分。
您如何告诉 React 构建(build)生产模式,该做什么?
使用 Webpack 的 DefinePlugin 方法将 NODE_ENV 设置为 production。这将剥离像 propType 验证和额外的警告。除此之外,还可以减少你的代码,因为 React 使用 Uglify 的 dead-code 来消除开发代码和注释,这将大大减少你的包的大小。
React Vue 动画
React
- 基于 React 组件状态的 CSS/JS 动画
- React Motion 库,Animated 库,Velocity React 库
<Motion defaultStyle={{left: 0}} style={{left: spring(10)}}>
{interpolatingStyle => <div style={interpolatingStyle} />}
</Motion>
指定一个初始style(defaultStyle),然后赋值一个目标style(style),中间每帧都会由react-motion计算出对应的style,用户只管使用生成的style(interpolatingStyle),不用关心物理效果的实现,动画中断的处理,一切事情都交给react-motion。
- react-addons-css-transition-group 插件,是利用 css 的 transition 和 animation 实现组件的进场和出场动画的。
Vue
- 内置组件 transition
<style>
.my-leave-to {
opacity: 0;
transform: translateY(100px);
}
.my-enter-active,
.my-leave-active {
transition: all 1s ease;
}
</style>
<transition name="my">
<h4 v-show="toggle333">v_animation</h4>
</transition>
- 利用 animate.css 结合 transition 实现动画
<transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{ enter: 200, leave: 2000}">
<h4 v-show="toggle444" class="animated">animate_css</h4>
</transition>
网友评论