大家好,我是 @洛竹
本文首发于 洛竹的官方网站
本文翻译自 sudheerj/reactjs-interview-questions
本文同步于公众号洛竹早茶馆,转载请联系作者。
1. createElement 和 cloneElement 的区别是什么?
JSX 元素将被转换为 React.createElement()
函数以创建 React 元素,这些元素将用于 UI 的对象表示。而 cloneElement
用于克隆元素并将新的 props
传递给它。
课后扩展:
2. React 中的状态提升是什么?
当多个组件需要共享相同的变化数据时,建议将共享状态提升到它们最接近的共同祖先。这意味着,如果两个子组件共享来自其父组件的相同数据,则将状态移到父组件,而不是在两个子组件中都保持内部状态。
3. 组件生命周期有哪些不同阶段?
组件生命周期具有三个不同的生命周期阶段。
- Mounting: 组件已准备好安装在浏览器 DOM 中。这个阶段涵盖了生命周期方法
constructor()
、getDerivedStateFromProps()
、render()
和componentDidMount()
的初始化。 - Updating: 在此阶段,组件以两种方式进行更新,即发送新
props
和从setState()
或forceUpdate()
更新状态。此阶段涵盖了getDerivedStateFromProps()
,shouldComponentUpdate()
,render()
、getSnapshotBeforeUpdate()
和componentDidUpdate()
生命周期方法。 - Unmounting: 在最后一个阶段,不再需要该组件并从浏览器DOM上卸载该组件。 这个阶段包括
componentWillUnmount()
生命周期方法。
值得一提的是,在将更改应用于 DOM 时,React 内部具有阶段性概念。 它们分开如下
- Render: 该组件将渲染而没有任何副作用。这适用于 Pure 组件,在此阶段,React 可以暂停、中止或重新启动渲染。
- Pre-commit: 在组件将更改实际应用于 DOM 之前,有一段时间可以让 React 通过
getSnapshotBeforeUpdate()
从 DOM 中读取内容。 - Commit: React 与 DOM 一起工作并分别执行最终的生命周期:
componentDidMount()
用于安装,componentDidUpdate()
用于更新,以及componentWillUnmount()
用于卸载。
React 16.3+ (或者 在线交互版本)
React 16.3 之前的版本:
4. React 生命周期有哪些?
React 16.3 以前的版本:
- componentWillMount: 在渲染之前执行,用于根组件中的应用程序级别配置。
- componentDidMount: 在首次渲染之后执行,所有 AJAX 请求,DOM 或状态更新以及设置事件侦听器都应在此执行。
- componentWillReceiveProps: 在特定属性更新以触发状态转换时执行。
- shouldComponentUpdate: 确定是否要更新组件。默认情况下,它返回
true
。如果你确定在状态或属性更新后不需要渲染组件,则可以返回false
值。这是提高性能的好地方,因为如果组件收到新的props
,它可以防止重新渲染。 - componentWillUpdate: 当有属性或状态改变被
shouldComponentUpdate()
确认并返回true
时,在重新渲染组件之前执行。 - componentDidUpdate: 通常,它用于响应属性或状态更改来更新 DOM。
- componentWillUnmount: 它将用于取消任何传出的网络请求,或删除与该组件关联的所有事件侦听器。
React 16.3+ 版本
- getDerivedStateFromProps: 在调用
render()
之前被调用,并且在每次渲染中都会被调用。对于需要派生状态的罕见用例,这是存在的。如果您需要派生状态 值得一读。 - componentDidMount: 在首次渲染之后执行,并且所有 AJAX 请求、DOM 或状态更新以及设置事件侦听器都应在此发生。
- shouldComponentUpdate: 确定是否将更新组件。默认情况下,它返回
true
。如果你确定在状态或属性更新后不需要渲染组件,则可以返回false
值。这是提高性能的好地方,因为如果组件接收到新的属性,它可以防止重新渲染。 - getSnapshotBeforeUpdate: 在将呈现的输出提交给 DOM 之前立即执行。此方法返回的任何值都将传递到
componentDidUpdate()
中。 这对于从 DOM(即滚动位置)捕获信息很有用。 - componentDidUpdate: 通常,它用于响应属性或状态更改来更新DOM。如果
shouldComponentUpdate()
返回false
,则不会触发。 - componentWillUnmount: 它将用于取消任何传出的网络请求,或删除与该组件关联的所有事件侦听器。
5. 高阶组件是什么
高阶组件(HOC)是接收组件并返回新组件的函数。基本上,这是从 React 的组成性质衍生出来的一种模式。
我们称它们为纯组件,因为它们可以接受任何动态提供的子组件,但是它们不会修改或复制其输入组件中的任何行为。
const EnhancedComponent = higherOrderComponent(WrappedComponent)
HOC 可以用到很多场景中:
- 代码重用,逻辑和引导程序抽象。
- 渲染劫持。
- 状态抽象和操纵。
- props操作。
6. 如何为 HOC 组件 创建 props 代理?
您可以使用属性代理模式添加或编辑传递给组件的属性,如下所示:
function HOC(WrappedComponent) {
return class Test extends Component {
render() {
const newProps = {
title: 'New Header',
footer: false,
showFeatureX: false,
showFeatureY: true
}
return <WrappedComponent {...this.props} {...newProps} />
}
}
}
课后扩展:
7. context 是什么?
Context
提供了一种通过组件树传递数据的方法,而不需要一层一层手动传递属性。
例如,需要由许多组件在应用程序中访问经过身份验证的用户,本地设置首选项,UI 主题等。
const {Provider, Consumer} = React.createContext(defaultValue)
8. 什么是 children 属性?
Children
是一个 prop(this.props.children
),允许你将组件作为数据传递给其他组件,就像你使用的任何其他 prop 一样。放置在组件的开始标记和结束标记之间的组件树将作为 children
道具传递给该组件。
React API 中有许多方法可作为该属性。其中包括 React.Children.map
、React.Children.forEach
,React.Children.count
、React.Children.only
和 React.Children.toArray
。
children 的简单用法如下所示:
const MyDiv = React.createClass({
render: function() {
return <div>{this.props.children}</div>
}
})
ReactDOM.render(
<MyDiv>
<span>{'Hello'}</span>
<span>{'World'}</span>
</MyDiv>,
node
)
9. React 中如何写注释?
React JSX 中的注释和 JavaScript 的多行注释很像,但是用大括号括起来。
单行注释:
<div>
{/* 这里是单行注释 */}
{`Welcome ${user}, let's play React`}
</div>
多行注释:
<div>
{/* Multi-line comments for more than
one line */}
{`Welcome ${user}, let's play React`}
</div>
10. 在 constructor 中给 super
函数传递 props 的目的是什么?
一个子类构造器在 super()
方法调用之前是无法拿到 this
引用的。这同样也适用于 ES6 中的 sub-classes。调用 super()
时传递 props 的主要是为了在子类的构造器中访问 this.props
。
传递 props:
class MyComponent extends React.Component {
constructor(props) {
super(props)
console.log(this.props) // 打印 { name: 'John', age: 42 }
}
}
不传递 props:
class MyComponent extends React.Component {
constructor(props) {
super()
console.log(this.props) // 打印 undefined
// 但是 props 参数依然可以访问
console.log(props) // 打印 { name: 'John', age: 42 }
}
render() {
// 在 constructor 之外没有影响
console.log(this.props) // 打印 { name: 'John', age: 42 }
}
}
上面的代码片段揭示了 this.props
仅在构造函数中有所不同。在构造函数外部表现将是相同的。
更多信息可以参考 为什么我们要写 super(props) ?
结语
关注公众号洛竹早茶馆
,一个持续分享编程知识的地方。
点赞
等于学会,在看
等于精通- 最后祝大家 2021 学习进步,升职加薪